Kế thừa lai ghép và lớp cơ sở ảo

Một phần của tài liệu Lập trình hướng đối tượng (Trang 138 - 141)

- Lớp CON kế thừa trực tiếp từ lớp CHA và lớp ME, ngoài ra lớp CON còn kế thừa từ lớp ONGBA theo 2 con đ- ờng khác nhau. Nó kế thừa trực tiếp một số đặc tính từ lớp ONGBA (đờng chấm chấm) và kế thừa gián tiếp một số đặc tính qua 2 lớp CHA và lớp ME.

- Nh vậy thành phần protected và public của lớp ONGBA sẽ đợc kế thừa đúp ở lớp CON, lần thứ nhất kế thừa từ lớp CHA, lần thứ 2 kế thừa từ lớp ME, nghĩa là lớp CON sẽ có 2 tập thành phần kế thừa khác nhau. Vậy vấn đề đặt ra là phải có cơ chế loại bỏ d thừa trong quan hệ kế thừa lai ghép.

- C++ cho phép loại bỏ d thừa trong quan hệ kế thừa lai ghép bằng cơ chế lớp cơ sở ảo và nó đợc chỉ ra bằng từ khoá virtual đặt sau tên lớp và trớc mode private / public. Khi 1 lớp đợc khai báo là lớp cơ sở ảo thì chỉ có 1 bản sao duy nhất những thành phần đợc kế thừa đợc truyền cho lớp kế thừa cho dù có bao nhiêu đờng kế thừa cũng thế.

Ôngbà

Mẹ Cha

class A // ONGBA { // noi dung lop A };

class B1: virtual public A // CHA { // noi dung lop B1};

class B2: virtual public A // ME { // noi dung lop B2 };

class C: public B1, public B2 // CON { // noi dung lop C};

Ví dụ 4 : #include <iostream.h> #include <conio.h> class A { protected: int x; public:

virtual void show() { cout <<" LOP A "<<endl; } };

class B1: virtual public A { protected:

int y1; public:

void show() { cout <<" LOP B1 "<<endl; } };

class B2: virtual public A { protected:

int y2; public:

void show() { cout <<" LOP B2 "<<endl; } };

{ private: int z; public:

void show() { cout <<" LOP C "<<endl; } }; int main() { clrscr(); A *ptr; C c; ptr=&c; ptr->show(); // LOP C B1 b1; ptr=&b1; ptr->show(); // LOP B1 B2 b2; ptr=&b1; ptr->show(); // LOP B2 getch(); return 0; } Nhận xét:

- Nếu 2 lớp cha B1 và B2 không khai báo lớp ảo thì chơng trình sẽ lỗi.

- Nếu hàm show của lớp A không khai báo ảo thì lệnh ptr->show() liên kết với hàm show của lớp A và hàm này kế thừa sang lớp cháu C qua 2 lớp cha B1 và B2 gồm 1 bản sao duy nhất chứ không sử dụng 2 hàm show() của 2 lớp cha B1 và B2 đó.

- Nếu hàm show của lớp A có khai báo ảo nh ở ví dụ thì lệnh ptr->show() liên kết với hàm show của lớp C. Tuy nhiên hàm ảo này vẫn kế thừa sang lớp cháu C bằng 1 bản sao duy nhất chứ không sử dụng 2 hàm show() của 2 lớp cha B1 và B2 đó.

Kết luận

* Hàm ảo ở lớp cơ sở để tránh nhập nhằng về các hàm cùng tên.

* Lớp ảo trong các lớp kế thừa trung gian để tránh lặp lại các thành phần theo các đờng khác nhau.

* Khi không có hàm ảo thì chú ý nguyên tắc 1 và nguyên tắc 2.

Một phần của tài liệu Lập trình hướng đối tượng (Trang 138 - 141)