Giả sử có một khai báo kế thừa như bên dưới.
class Animal {
// eat() function
// sleep() function
};
class Dog : public Animal {
// bark() function
};
Lớp Dog đang kế thừa public từ lớp Animal. Ngoài public, chúng ta có thể dùng private, protected. Vậy các dẫn xuất kế thừa này khác nhau như thế nào?
1. Tính kế thừa với các dẫn xuất public, protected, private trong C++
Kế thừa public có đặc điểm:
– Các thành phần public của lớp cơ sở trở thành các thành phần public trong lớp dẫn xuất.
– Các thành phần protected của lớp cơ sở trở thành các thành phần protected trong lớp dẫn xuất.
Kế thừa protected có đặc điểm:
Các thành phần public và protected của lớp cơ sở trở thành các thành phần protected trong lớp dẫn xuất.
Kế thừa private có đặc điểm:
Các thành phần public và protected của lớp cơ sở trở thành các thành phần private trong lớp dẫn xuất.
Lưu ý: các thành phần private của lớp cơ sở luôn không thể truy cập trong lớp dẫn xuất.
class Base {
public:
int x;
protected:
int y;
private:
int z;
};
class PublicDerived: public Base {
// x is public
// y is protected
// z is not accessible from PublicDerived
};
class ProtectedDerived: protected Base {
// x is protected
// y is protected
// z is not accessible from ProtectedDerived
};
class PrivateDerived: private Base {
// x is private
// y is private
// z is not accessible from PrivateDerived
}
2. Ví dụ kế thừa với dẫn xuất public
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
// function to access private member
int getPVT() {
return pvt;
}
};
class PublicDerived : public Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
};
int main() {
PublicDerived object1;
cout << "Private = " << object1.getPVT() << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.pub << endl;
return 0;
}
Kết quả
Private = 1
Protected = 2
Public = 3
Lớp PublicDerived kế thừa public từ lớp Base. Khi đó, prot trở thành thành phần protected, pub và getPVT() trở thành thành phần public của lớp PublicDerived. pvt không được truy cập trong lớp PublicDerive bởi nó là thành phần private trong lớp Base.
Các thành phần private và protected của lớp không thể truy cập trong hàm main(). Chúng ta cần tạo các hàm public là getPVT() và getProt() để truy cập chúng.
// Error: member "Base::pvt" is inaccessible
cout << "Private = " << object1.pvt;
// Error: member "Base::prot" is inaccessible
cout << "Protected = " << object1.prot;
Lưu ý: Hàm getPVT() được định nghĩa trong lớp Base còn hàm getProt() được định nghĩa trong lớp PublicDerived.
pvt là thành phần private trong Base và không thể truy cập trong PublicDerived. Các đối tượng của lớp PublicDerived chỉ có thể truy cập pvt thông qua hàm getPVT() được định nghĩa trong lớp Base và được kế thừa qua cho lớp PublicDerived.
prot có thể được truy cập bởi lớp PublicDerived vì kế thừa với dẫn xuất public. Vì thế, hàm getProt() có thể truy cập biến protected prot trong PublicDerived.
3. Ví dụ kế thừa với dẫn xuất protected
// C++ program to demonstrate the working of protected inheritance
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
// function to access private member
int getPVT() {
return pvt;
}
};
class ProtectedDerived : protected Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access public member from Base
int getPub() {
return pub;
}
};
int main() {
ProtectedDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Kết quả
Private cannot be accessed.
Protected = 2
Public = 3
Lớp ProtectedDerived kế thừa protected từ lớp Base. Khi đó, lớp ProtectedDerived sẽ có:
prot, pub và getPVT() là thành phần protected. pvt không thể truy cập được. Hàm getPVT() không thể được sử dụng bên ngoài lớp ProtectedDerived. Trong ví dụ trên là không thể sử dụng trong hàm main() bởi các đối tượng của lớp ProtectedDerived được.
Đó cũng là lý do cần tạo hàm getPub() để truy cập biến pub trong lớp ProtectedDerived.
// Error: member "Base::getPVT()" is inaccessible
cout << "Private = " << object1.getPVT();
// Error: member "Base::pub" is inaccessible
cout << "Public = " << object1.pub;
4. Ví dụ kế thừa với dẫn xuất private
// C++ program to demonstrate the working of private inheritance
#include <iostream>
using namespace std;
class Base {
private:
int pvt = 1;
protected:
int prot = 2;
public:
int pub = 3;
// function to access private member
int getPVT() {
return pvt;
}
};
class PrivateDerived : private Base {
public:
// function to access protected member from Base
int getProt() {
return prot;
}
// function to access private member
int getPub() {
return pub;
}
};
int main() {
PrivateDerived object1;
cout << "Private cannot be accessed." << endl;
cout << "Protected = " << object1.getProt() << endl;
cout << "Public = " << object1.getPub() << endl;
return 0;
}
Kết quả
Private cannot be accessed.
Protected = 2
Public = 3
Lớp PrivateDerived kế thừa private từ lớp Base. Khi đó, lớp PrivateDerived sẽ có:
prot, pub và getPVT() là thành phần private. pvt không thể truy cập được. Hàm getPVT() không thể được sử dụng bên ngoài lớp PrivateDerived. Trong ví dụ trên là không thể sử dụng trong hàm main() bởi các đối tượng của lớp PrivateDerived được.
Đó cũng là lý do cần tạo hàm getPub() để truy cập biến pub trong lớp PrivateDerived.
// Error: member "Base::getPVT()" is inaccessible
cout << "Private = " << object1.getPVT();
// Error: member "Base::pub" is inaccessible
cout << "Public = " << object1.pub;
Tài liệu tham khảo: C++ Public, Protected and Private Inheritance.