Dẫn xuất public, protected, private trong kế thừa và minh họa với C++

Đây là bài 13/19 bài của series môn học Lập trình hướng đối tượng

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 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, pubgetPVT() 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 privateprotected 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 publicgetPVT()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, pubgetPVT() 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, pubgetPVT() 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.

5/5 - (1 bình chọn)
Bài trước và bài sau trong môn học<< Khái niệm kế thừa và đơn kế thừa trong lập trình hướng đối tượngLớp dẫn xuất (derived class) trong lập trình hướng đối tượng với C++ >>
Chia sẻ trên mạng xã hội:

Trả lời

Lưu ý:

1) Vui lòng bình luận bằng tiếng Việt có dấu.

2) Khuyến khích sử dụng tên thật và địa chỉ email chính xác.

3) Mọi bình luận trái quy định sẽ bị xóa bỏ.