Phương thức ghi đè cuộc gọi cha mẹ Python

Đối với mã ví dụ sau, PPC của lớp cha sử dụng slef. forward(x)
để gọi hàm của lớp con.

Tôi không thể hiểu những câu hỏi sau đây

  1. forward không phải là một hàm ảo, làm sao lớp cha có thể gọi nó?

Python không có phương thức ảo

  1. làm thế nào để lớp cha mẹ tìm thấy phía trước?

Nó không. Điều này sẽ chỉ hoạt động trong một phiên bản của PPSub

  1. trong mã ví dụ của tôi, nếu tôi sử dụng phương pháp trừu tượng, nó có phải là một cú pháp tốt hơn không?

Chắc chắn là phong cách và thực hành tốt hơn. Cú pháp là cú pháp. Nếu cú ​​pháp
hợp pháp thì bạn ổn.

Hãy xem xét điều này kỹ hơn

PPC là một lớp trừu tượng. Nó sử dụng. forward(), nhưng không cung cấp một.
Nếu bạn khởi tạo phiên bản PPC, lệnh gọi sẽ không hoạt động.

PPSub là một phân lớp cụ thể của PPC. nó cung cấp một. forward()
triển khai. Nếu bạn tạo một phiên bản của PPSub, phương thức gọi của nó
sẽ hoạt động.

Khi bạn gọi

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

1, nó sẽ chuyển sang phương thức gọi. PPSub không
thực hiện điều này, nhưng lớp cha của nó thì có. Vì vậy, được sử dụng. Phương thức đó
lần lượt gọi

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

2. Nhưng nó phát hiện ra rằng từ

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

3, một
thực thể của PPSub và PPSub thực hiện

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

2.

Ngày nay, Python đã hỗ trợ tạo các lớp trừu tượng
một cách chặt chẽ hơn. Hãy cập nhật mã của bạn bằng cách sử dụng nó.

from abc import ABC, abstractmethod

@ABC
class PPC():

    def kkfunc(self):
        print('kk func in parent class')

    def __call__(self, x):
        xx= self.forward(x)
        # print('call function === ', x)
        return xx

    @abstractmethod
    def forward(self, x):
        raise NotImplementedError("no .forward method")

class PPSub(PPC):
    def __init__(self):
        pass

    def pfunc(self):
        print('in sub class')

    def forward(self, x):
        print('forward function in ppsub class===', x)
        return x+1

ps1 = PPSub()
xxx = ps1(9)

Điều này không thay đổi cách hoạt động của bất kỳ lớp nào, nhưng trình trang trí

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

5 và

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

6 sắp xếp khiến bạn thực sự không thể tạo
. Trình trang trí

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

5 làm cho lớp kiểm tra xem không có
phương thức nào của nó là phương thức trừu tượng.

PPSub sẽ kế thừa hành vi đó, nhưng vì nó cung cấp một

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

2
không phải là phương thức trừu tượng nên nó không có phương thức trừu tượng và bạn
được phép .

Chúc mừng!
Cameron Simpson cs@cskk. Tôi. au

Rất cảm ơn câu trả lời chuyên nghiệp và chi tiết của bạn.
Tôi muốn cố gắng hiểu nhận xét của bạn và thêm một vài câu hỏi nữa.

  1. cú pháp trong mã ví dụ của tôi là tốt

Trình thông dịch python có chấp nhận nó không?

Lớp cha sẽ không tìm thấy hàm chuyển tiếp dưới dạng ‘self’ của
self. chuyển tiếp đề cập đến thể hiện của lớp con, nhưng không phải lớp cha.

Có. Tra cứu một phương thức trên một thể hiện của lớp, thử chính lớp đó, sau đó
các lớp cha theo thứ tự phân giải phương thức (từ
type(instance). mro nếu bạn muốn xem nó).

  1. python có lớp trừu tượng mới và phương thức để giải quyết câu hỏi tôi đang gặp phải

Có, mô-đun tiêu chuẩn “abc”

  1. bộ giải mã @ABC giống như.
    https://docs.python.org/3/library/abc.html#module-abc
    
    0, hiểu biết của tôi có đúng không?

tôi nghĩ vậy

  1. @abstractmethod tương tự như hàm ảo trong C++ phải không?

Có. Mặc dù C++ của tôi yếu. Ý tưởng là trình bày phương thức dưới dạng
phương thức bắt buộc, nhưng chỉ ra rằng lớp này không triển khai phương thức đó.

  1. khi nào tính năng phương thức và lớp trừu tượng được thêm vào python?
  2. bạn có bất kỳ liên kết hoặc tài liệu nào giải thích về lớp trừu tượng
    và phương thức bằng ngôn ngữ python không?

Python 3 tôi nghĩ. Tài liệu mô-đun tại đây

https://docs.python.org/3/library/abc.html#module-abc

Nhiều bit được thêm vào trong các bản phát hành cụ thể của Python như được chỉ ra bởi
các ghi chú như “Mới trong phiên bản 3. 4. ”.

Chúc mừng!
Cameron Simpson cs@cskk. Tôi. au

Kế thừa là một khái niệm trong lập trình hướng đối tượng trong đó một lớp con (hoặc lớp con) lấy các thuộc tính và hành vi từ lớp cha hoặc lớp anh chị em

Điều này giúp loại bỏ nhu cầu triển khai lại các phương thức được kế thừa bởi một lớp con hoặc lớp con. Nói cách khác, nó cho phép lớp con kế thừa/tái sử dụng các thuộc tính và phương thức của lớp cha. Về các đối tượng trong thế giới thực, nó thể hiện mối quan hệ IS-A

class Python(ProgramLanguage):

Trong đoạn mã trên, lớp con

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

3 kế thừa biến

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

4 và phương thức

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

5 từ lớp cơ sở

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

6. Câu lệnh

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

7 hoạt động như một trình giữ chỗ cho nội dung lớp

Các phương thức của lớp cơ sở có thể được sử dụng lại trong các lớp dẫn xuất. Điều này ngăn chặn mã dự phòng

Trong ví dụ dưới đây, lớp dẫn xuất,

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

3, triển khai phương thức cha

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

9 bên trong định nghĩa
https://docs.python.org/3/library/abc.html#module-abc
10

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

Đầu ra sẽ là

https://docs.python.org/3/library/abc.html#module-abc
1

Ghi chú. Bên trong lớp con, cùng một số lượng và loại đối số cần được truyền vào phương thức của lớp cha

Trong lớp con, một phương thức của lớp cha bị ghi đè khi một phương thức cùng tên được khai báo bên trong nó

https://docs.python.org/3/library/abc.html#module-abc
4

Nếu một phương thức bị ghi đè trong lớp con, thì phương thức ban đầu vẫn có thể được truy cập bằng cách gọi phương thức đó trực tiếp trên tên lớp cha và chuyển đối tượng của lớp con làm đối số

https://docs.python.org/3/library/abc.html#module-abc
5

Đầu ra sẽ là

https://docs.python.org/3/library/abc.html#module-abc
6

Khi các biến thể hiện của lớp cha không cần phải được kế thừa bởi lớp con, chúng có thể không khả dụng đối với lớp con bằng cách thêm hai dấu gạch dưới (

https://docs.python.org/3/library/abc.html#module-abc
11) trước tên biến. Điều này nối thêm
https://docs.python.org/3/library/abc.html#module-abc
12 trước tên biến. Vì vậy, khi chúng tôi cố gắng truy cập nó giống như các biến đối tượng khác của lớp, nó sẽ báo “Lỗi thuộc tính”

https://docs.python.org/3/library/abc.html#module-abc
9

lỗi sẽ là

https://docs.python.org/3/library/abc.html#module-abc
0

https://docs.python.org/3/library/abc.html#module-abc
13 trong lớp cha

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

6 hiện là
https://docs.python.org/3/library/abc.html#module-abc
15 và không thể truy cập được bằng cách sử dụng
https://docs.python.org/3/library/abc.html#module-abc
16. Điều này cũng đúng với các phương thức của lớp

Ghi chú. Việc sử dụng tiền tố gạch dưới kép chỉ làm cho phương thức hoặc biến không thể truy cập được bằng tên được khai báo ban đầu. Chúng vẫn có thể được truy cập, như

https://docs.python.org/3/library/abc.html#module-abc
17 trong ví dụ trên. Việc sử dụng cú pháp này là một dấu hiệu cho thấy biến hoặc phương thức nên được xử lý như thế nào

https://docs.python.org/3/library/abc.html#module-abc 18 và https://docs.python.org/3/library/abc.html#module-abc 19

Python có hai hàm tích hợp hoạt động với tính kế thừa

  • https://docs.python.org/3/library/abc.html#module-abc
    
    18
  • https://docs.python.org/3/library/abc.html#module-abc
    
    41

https://docs.python.org/3/library/abc.html#module-abc
18 kiểm tra loại của một thể hiện

Đoạn mã trên sẽ là

https://docs.python.org/3/library/abc.html#module-abc
43 chỉ khi
https://docs.python.org/3/library/abc.html#module-abc
44 là một đối tượng của lớp
https://docs.python.org/3/library/abc.html#module-abc
45 hoặc một đối tượng của một số lớp dẫn xuất của
https://docs.python.org/3/library/abc.html#module-abc
45

https://docs.python.org/3/library/abc.html#module-abc
19 kiểm tra tính kế thừa của lớp

https://docs.python.org/3/library/abc.html#module-abc
48 là lớp con của
https://docs.python.org/3/library/abc.html#module-abc
45 nên nó trả về
https://docs.python.org/3/library/abc.html#module-abc
43. Tuy nhiên, vì
https://docs.python.org/3/library/abc.html#module-abc
51 không phải là lớp con của
https://docs.python.org/3/library/abc.html#module-abc
45, nên nó trả về
https://docs.python.org/3/library/abc.html#module-abc
53

Các lớp cơ sở trừu tượng được kế thừa thay vì được khởi tạo

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

2

https://docs.python.org/3/library/abc.html#module-abc
54 có nguồn gốc từ
https://docs.python.org/3/library/abc.html#module-abc
55, làm cho nó trở thành Lớp cơ sở trừu tượng. Điều này cho người dùng mô-đun biết rằng
https://docs.python.org/3/library/abc.html#module-abc
54 không thể được khởi tạo, chỉ được kế thừa

https://docs.python.org/3/library/abc.html#module-abc
57 được trang trí bằng
https://docs.python.org/3/library/abc.html#module-abc
58, biểu thị nó là một phương pháp trừu tượng. Điều này cho các nhà phát triển biết rằng nếu họ muốn kế thừa từ
https://docs.python.org/3/library/abc.html#module-abc
54, họ phải ghi đè phương thức
https://docs.python.org/3/library/abc.html#module-abc
57. Mặt khác, lớp dẫn xuất không thể được khởi tạo

Thừa kế đơn

Khi một lớp con chỉ kế thừa từ một lớp cha, nó được gọi là kế thừa đơn. Tất cả các đoạn mã trước sử dụng kế thừa duy nhất

Đa thừa kế

Khi một lớp con kế thừa từ nhiều lớp cha, nó được gọi là đa kế thừa

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

3 IS-A

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

6 và một
https://docs.python.org/3/library/abc.html#module-abc
63;

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

3

Đầu ra sẽ là

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

0

Kế thừa đa cấp

Khi một lớp dẫn xuất kế thừa từ một lớp dẫn xuất khác

Trong đoạn mã dưới đây, lớp

https://docs.python.org/3/library/abc.html#module-abc
64 kế thừa từ lớp
https://docs.python.org/3/library/abc.html#module-abc
65

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

1

Kế thừa phân cấp

Nhiều hơn một lớp dẫn xuất được tạo từ một lớp cơ sở duy nhất

print("Hi! I am a Programming Language.")

class Python(ProgramLanguage):

2

Kế thừa lai

Hình thức này là sự pha trộn của nhiều loại thừa kế đã đề cập ở trên

Sự cố nổ lớp

Mặc dù một chương trình có thể hoạt động như mong đợi, nhưng việc có nhiều lớp để hỗ trợ việc triển khai ý tưởng sẽ gây ra sự phát triển không thể tránh khỏi của hệ thống phân cấp lớp. Tất cả điều này dẫn đến vấn đề bùng nổ lớp trong đó hệ thống phân cấp lớp trở nên quá rộng và khiến mã khó hiểu và khó bảo trì.

bài toán kim cương

Vấn đề kim cương là một sự mù mờ phát sinh trong đa kế thừa

Các lớp,

https://docs.python.org/3/library/abc.html#module-abc
66 và
https://docs.python.org/3/library/abc.html#module-abc
67, kế thừa từ lớp
https://docs.python.org/3/library/abc.html#module-abc
68 và lớp
https://docs.python.org/3/library/abc.html#module-abc
69 kế thừa từ cả hai lớp
https://docs.python.org/3/library/abc.html#module-abc
66 và
https://docs.python.org/3/library/abc.html#module-abc
67. Nếu có một phương thức trong
https://docs.python.org/3/library/abc.html#module-abc
68 mà
https://docs.python.org/3/library/abc.html#module-abc
66 và
https://docs.python.org/3/library/abc.html#module-abc
67 đã ghi đè và
https://docs.python.org/3/library/abc.html#module-abc
69 không ghi đè lên nó, thì phiên bản nào của phương thức sẽ kế thừa
https://docs.python.org/3/library/abc.html#module-abc
69. của B hay của C?

Thứ tự của các lớp cha quyết định lớp

https://docs.python.org/3/library/abc.html#module-abc
69 kế thừa từ. Để gọi hàm cha được chọn, phương thức super() được gọi bên trong lớp con

Làm cách nào chúng ta có thể gọi phương thức được ghi đè của lớp cha trong Python?

Ghi đè phương thức là khả năng của bất kỳ ngôn ngữ lập trình hướng đối tượng nào cho phép lớp con hoặc lớp con cung cấp triển khai cụ thể của phương thức đã được cung cấp bởi một trong các siêu lớp của nó. . .

Có @override trong Python không?

Ghi đè phương thức trong Python là khi bạn có hai phương thức có cùng tên, mỗi phương thức thực hiện các tác vụ khác nhau . Đây là một tính năng quan trọng của tính kế thừa trong Python. Trong ghi đè phương thức, lớp con có thể thay đổi các chức năng được định nghĩa bởi các lớp tổ tiên của nó.

Lớp cha có thể truy cập các phương thức con Python không?

Là một phần của OOPS và tránh lặp lại mã, bạn có thể truy cập các phương thức của lớp cha từ lớp con . Tương tự, ngược lại.

Chúng ta có thể gọi phương thức của lớp con bằng cách sử dụng tham chiếu gốc không?

Sau đó, lớp con có thể định nghĩa các phương thức riêng của nó, không được định nghĩa trong lớp cha và không được kế thừa bởi lớp con. Trình biên dịch Java kiểm tra tính đa hình thời gian biên dịch. Ở đó, nếu bạn đang gọi một phương thức của đối tượng con được định nghĩa trong chính lớp con đó, bằng cách sử dụng tham chiếu cha