5 .3| Cerr và clog
5.4 .6| Tầm vực trong kế thừa
Khi cài đặt kế thừa trong lập trình hướng đối tượng người ta vẫn phải quan tâm đến tính đóng gói và che giấu thơng tin. Điều này ảnh hưởng đến phạm vi truy xuất các thành phần trong class. Một lớp kế thừa (Derived Class) sẽ kế thừa tất cả các phương thức của lớp cơ sở, ngoại trừ:
• Constructor, destructor và copy constructor của lớp cơ sở. • Overloaded operator (tốn tử nạp chồng) của lớp cơ sở.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 93
− Truy xuất theo chiều dọc: Hàm thành phần của lớp con có quyền truy xuất
các thành phần của lớp cha hay không?
Truy xuất theo chiều dọc cụ thể ở trên lớp dẫn xuất (derived class) chỉ có thể truy cập các thành phần Public và Protected của lớp cơ sở (base class). Cịn các hàm bạn, lớp bạn thì có thể truy cập tất cả. Những hàm hoặc lớp khơng có mối quan hệ với đó thì chỉ sử dụng được các thành viên public.
−
− Truy xuất theo chiều dọc
− Truy xuất theo chiều ngang: Các thành phần của lớp cha, sau khi kế thừa
xuống lớp con, thì thế giới bên ngồi có quyền truy xuất thơng qua đối tượng của lớp con hay khơng?
Truy xuất theo chiều ngang có nghĩa là việc lớp con quyết định kế thừa theo public, protected hay private có ảnh hưởng đến việc truy cập các thành phần của class cha.
Kiểu kế thừa Public: Trong trường một một sub class được dẫn xuất từ một public base class thì các thành viên public của base class trở thành thành viên public của sub class, thành viên protected của base class cũng là thành viên protected của sub class. Các thành viên private của base class không được thừa kế trong sub class.
Kiểu kế thừa Protected: khi một sub class được dẫn xuất từ một protected base class thì cả hai loại thành viên public và protected trong base class sẽ trở thành thành viên protected trong derived class. Các thành viên private của base class không được thừa kế trong sub class.
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 94
Kiểu kế thừa Private: khi một sub class được dẫn xuất từ một private base class thì cả hai loại thành viên public và protected trong base class sẽ trở thành thành viên private trong derived class. Các thành viên private của base class không được thừa kế trong sub class.
Quan sát ví dụ sau để hiểu hơn về cơ chế kế thừa: class B {
// Other details omitted public:
void f(); }; void B::f() {
std::cout << "In function 'f'\n"; }
class D: public B {
// Other details omitted public:
void g(); }; void D::g() {
std::cout << "In function 'g'\n"; }
Code phía client: B myB; D myD; myB.f(); myD.f(); myD.g(); Kết quả: In function 'f' In function 'f' In function 'g'
Mặc dù mã nguồn của lớp D không hiển thị rõ ràng định nghĩa của một phương thức có tên f, nó có một phương thức mà nó kế thừa từ lớp B.
Lưu ý rằng kế thừa chỉ hoạt động theo một hướng. Lớp D thừa kế phương thức f từ lớp B, nhưng lớp B không thể kế thừa phương thức d của lớp D. Với các định nghĩa của các lớp B và D ở trên, đoạn mã sau đây là không đúng:
B myB;
Tài liệu giảng dạy Kỹ Thuật Lập Trình 2 Trang 95
Khơng có giới hạn số lượng lớp kế thừa từ lớp cơ sở:
class D1: public B {/* Details omitted */}; class D2: public B {/* Details omitted */}; class D3: public B {/* Details omitted */}; Lớp D1, D2 và D3 được kế thừa từ lớp B.
Lập trình viên có thể khai báo một derived class có nhiều hơn một base class gọi là đa kế thừa (multiple inheritance) như sau :
class B1 {/* Details omitted */}; class B2 {/* Details omitted */};
class D: public B1, public B2 {/* Details omitted */};
Lớp D có 2 lớp cha là B1 và B2.
Thông thường các hàm hay phương thức cần object B1 hoặc B2 thì ta có thể thay thế object D. Trong thiết kế hướng đối tượng việc sử dụng đa kế thừa khơng phổ biến vì rất khó kiểm sốt và re-use, đơi khi cũng dùng nhưng là rất hiếm. Ta có thể dùng generic template thay thế cho Multiple Inheritance.