Bằng cách đặt quyền thừa kế ở chế độ riêng tư, về cơ bản bạn đang nói rằng ngay cả thực tế là B thừa kế từ A (hoàn toàn) là riêng tư - không thể truy cập / hiển thị với thế giới bên ngoài.
Không cần phải thảo luận dài dòng về những gì sẽ xảy ra nếu nó được cho phép, sự thật đơn giản là nó không được phép. Nếu bạn muốn sử dụng một con trỏ để cơ sở để tham chiếu đến một đối tượng có kiểu dẫn xuất, thì bạn đang gặp khá nhiều khó khăn với việc sử dụng kế thừa công khai.
Thừa kế riêng không nhất thiết (hoặc thậm chí bình thường) nhằm tuân theo nguyên tắc thay thế Liskov . Thừa kế công khai khẳng định rằng một đối tượng dẫn xuất có thể được thay thế cho một đối tượng của lớp cơ sở và ngữ nghĩa phù hợp vẫn sẽ dẫn đến kết quả. Thừa kế riêng không khẳng định điều đó. Mô tả thông thường về mối quan hệ được ngụ ý bởi thừa kế riêng là "được thực hiện theo điều kiện của".
Kế thừa công khai có nghĩa là một lớp dẫn xuất duy trì tất cả các khả năng của lớp cơ sở và có khả năng bổ sung thêm bên cạnh đó. Kế thừa riêng thường ít nhiều có nghĩa ngược lại: rằng lớp dẫn xuất sử dụng một lớp cơ sở chung để triển khai thứ gì đó với giao diện hạn chế hơn.
Ví dụ, chúng ta hãy giả sử rằng các vùng chứa trong thư viện chuẩn C ++ được triển khai bằng cách sử dụng kế thừa chứ không phải mẫu. Trong hệ thống hiện tại, std::deque
và std::vector
là các vùng chứa và std::stack
là một bộ điều hợp vùng chứa cung cấp giao diện hạn chế hơn. Vì nó dựa trên các mẫu, bạn có thể sử dụng std::stack
làm bộ điều hợp cho một trong hai std::deque
hoặc std::vector
.
Nếu chúng tôi muốn cung cấp về cơ bản giống với kế thừa, chúng tôi có thể sẽ sử dụng kế thừa riêng, vì vậy std::stack
sẽ giống như:
class stack : private vector {
};
Trong trường hợp này, chúng tôi chắc chắn không muốn người dùng có thể thao túng chúng tôi stack
như thể nó là một vector
. Làm như vậy có thể (và có khả năng) sẽ vi phạm các kỳ vọng về ngăn xếp (ví dụ: người dùng có thể chèn / xóa các mục ở giữa, thay vì theo kiểu hoàn toàn giống ngăn xếp như dự định). Về cơ bản chúng tôi đang sử dụng vector
như một cách thuận tiện để triển khai ngăn xếp của mình, nhưng nếu (ví dụ) chúng tôi đã thay đổi việc triển khai thành stack
một mình (không phụ thuộc vào một lớp cơ sở) hoặc triển khai lại nó về mặt std::deque
, chúng tôi không muốn điều đó để ảnh hưởng đến bất kỳ mã máy khách nào - đối với mã máy khách, điều này được cho là chỉ là một ngăn xếp, không phải là một số vector (hoặc deque) chuyên biệt nào đó.
protected