Mặc dù người ta có thể biện minh cho nhiều kế thừa thông qua việc kháng cáo một số khía cạnh triết học của OOP [ví dụ: chỉ ra rằng có vô số thiết bị có thể được coi là "điện thoại" và "máy tính" một cách hợp pháp theo bất kỳ định nghĩa hợp lý nào về các thuật ngữ đó], khi
Kế thừa không chỉ đơn thuần là một cấu trúc triết học; . Và các cơ chế ngôn ngữ có thể được sử dụng để hoàn thành các nhiệm vụ khác nhau. Cụ thể, tính kế thừa trong C++ gần như là cách duy nhất để một lớp có các phương thức và chức năng được đưa vào từ bên ngoài
Ví dụ: giả sử bạn có cấu trúc như std::shared_ptr
. Đây là một lớp mẫu đại diện cho quyền sở hữu của một T
từ nhiều chủ sở hữu. Một điều đôi khi có thể hữu ích là khả năng chuyển đổi một con trỏ/tham chiếu thành một T
thuộc sở hữu của một shared_ptr
thành một shared_ptr
. Nghĩa là, ai đó đã đưa cho bạn một con trỏ/tham chiếu và bây giờ bạn muốn xác nhận quyền sở hữu [được chia sẻ] thông qua con trỏ/tham chiếu đó
Bây giờ nếu điều đó hiệu quả, rõ ràng T
cần biết rằng điều này là có thể, vì bạn cần gọi một hàm giao diện của T
để làm điều đó. Nhưng T
cần nhiều hơn là chỉ biết rằng điều này là có thể. Khi một shared_ptr
được xây dựng, nó sẽ tạo ra một khối lưu trữ để quản lý thời gian tồn tại của đối tượng. Để T
có giao diện xác nhận quyền sở hữu của chính nó, nó cần có quyền truy cập vào khối lưu trữ này. Điều đó có nghĩa là hàm tạo của shared_ptr
cần móc vào T
mà nó đang được bao quanh để nó có thể ký gửi một loại con trỏ nào đó vào khối lưu trữ này
Cho nên. nó hoạt động như thế nào? . kế thừa từ một lớp cơ sở. Hàm tạo shared_ptr
có thể sử dụng siêu lập trình cơ bản để phát hiện xem T
có được dẫn xuất từ lớp cơ sở này hay không, sau đó sử dụng API riêng để thực hiện công việc của mình với nó. Cụ thể, loại T
phải kế thừa từ T
5
Và vâng, tôi đã không viết sai. T
phải kế thừa từ một lớp cơ sở được tạo khuôn mẫu trên chính T
. Thật vậy, thủ thuật này [kế thừa từ một lớp cơ sở được tạo khuôn mẫu trên tên lớp dẫn xuất] phổ biến đến mức nó có một cái tên. mẫu mẫu định kỳ tò mò
Đây là một cơ chế để triển khai một dạng chức năng mixin trong C++. Bạn có thể gộp các chức năng chung vào một lớp cơ sở và thông qua sự kỳ diệu của các mẫu, bạn có thể sử dụng tên lớp dẫn xuất [mặc dù nó chưa được định nghĩa chính xác] theo một số cách cụ thể cho phép bạn gọi các hàm của lớp dẫn xuất từ các hàm của lớp cơ sở
Điều này được thực hiện bởi vì tính kế thừa là công cụ duy nhất mà C++ có để tác động đến giao diện thành viên của lớp từ bên ngoài lớp
Đây là điều, mặc dù. Không có lý do gì mà T
8 không thể cùng tồn tại với một số chức năng lớp cơ sở CRTP khác. Không có lý do tại sao một loại không thể kích hoạt chia sẻ từ điều này và kích hoạt một số chức năng khác. Miễn là các mixin không xung đột về mặt giao diện, thì chúng vẫn ổn, vì về cơ bản, không ai trực tiếp sử dụng chính lớp cơ sở đó
Đa kế thừa là một tính năng trong đó một lớp có thể kế thừa các thuộc tính và phương thức từ nhiều hơn một lớp cha
Để tôi nói cho bạn biết Python không hỗ trợ đa kế thừa như các ngôn ngữ khác như Java, Ruby, v.v. Tuy nhiên, chúng ta có thể đạt được nó bằng MRO
Thứ tự giải quyết phương pháp [MRO] trong PythonTrong kịch bản đa thừa kế, bất kỳ thuộc tính cụ thể nào được tìm kiếm đầu tiên trong lớp hiện tại. Nếu không tìm thấy, quá trình tìm kiếm tiếp tục vào các lớp cha theo chiều sâu, trái phải trước mà không tìm kiếm cùng một lớp hai lần
Hãy để tôi chỉ cho bạn qua nó bằng ví dụ. -
Tạo một tệp có tên myfile. py và dán các dòng sau vào đó
class A:
def show[self]:
print["show of A called"]class B[A]:
def show[self]:
print["show of B called"]
class C[A]:
def show[self]:
print["show of C called"]class D[B,C]:
passx = D[] # Creating object
x.show[]
Vui lòng chạy myfile. py
$ python myfile.pyOutput - show of B called
Nếu bạn muốn xem phương thức sẽ được gọi theo thứ tự nào, hãy gõ lệnh bên dưới
$ print[D.__mro__]
Output - >
[, , , , ]
siêu trong Python
- Cho phép chúng tôi tránh sử dụng lớp cơ sở một cách rõ ràng
- Làm việc với nhiều kế thừa
Hãy lấy một ví dụ-
class A:
def show[self]:
print["show of A called"]class B[A]:
def show[self]:
print["show of B called"]
class C[A]:
def show[self]:
print["show of C called"]class D[B,C]:
def show[self]:
super[D, self].show[]
print["show of D called"]x = D[] # Creating object
x.show[]
Nếu bạn muốn gọi cha của lớp D thì có thể thực hiện được bằng từ khóa “super” như tôi đã đề cập trong ví dụ trên