Đa kế thừa có được phép trong Python không?

Trong chương trước của hướng dẫn, chúng ta đã đề cập đến tính kế thừa, hay cụ thể hơn là "kế thừa đơn lẻ". Như chúng ta đã thấy, trong trường hợp này, một lớp kế thừa từ một lớp. Mặt khác, đ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. Các nhà phê bình chỉ ra rằng đa thừa kế đi kèm với mức độ phức tạp và mơ hồ cao trong các tình huống như bài toán kim cương. Chúng ta sẽ giải quyết vấn đề này sau trong chương này

Định kiến ​​phổ biến rằng đa kế thừa là một thứ gì đó "nguy hiểm" hoặc "xấu" hầu hết được nuôi dưỡng bởi các ngôn ngữ lập trình với cơ chế đa kế thừa được triển khai kém và trên hết là do sử dụng nó không đúng cách. Java thậm chí không hỗ trợ đa kế thừa, trong khi C++ hỗ trợ nó. Python có một cách tiếp cận phức tạp và được thiết kế tốt để đa kế thừa

Một định nghĩa lớp, trong đó một lớp con SubClassName kế thừa từ các lớp cha BaseClass1, BaseClass2, BaseClass3, v.v., trông như thế này

class SubclassName[BaseClass1, BaseClass2, BaseClass3, ...]:
    pass

Rõ ràng là tất cả các lớp cha BaseClass1, BaseClass2, BaseClass3,. cũng có thể kế thừa từ các lớp cha khác. Những gì chúng ta nhận được là một cây thừa kế

Đào tạo Python trực tiếp

Thưởng thức trang này?

Nhìn thấy. Tổng quan về các khóa học Python trực tiếp

đăng ký tại đây

Thí dụ. LịchĐồng hồ

Chúng tôi muốn giới thiệu các nguyên tắc đa thừa kế với một ví dụ. Với mục đích này, chúng tôi sẽ triển khai cho các lớp độc lập. lớp "Đồng hồ" và lớp "Lịch". Sau đó, chúng tôi sẽ giới thiệu một lớp "CalendarClock", đúng như tên gọi của nó, là sự kết hợp của "Clock" và "Calendar". CalendarClock kế thừa cả từ "Đồng hồ" và "Lịch"

Lớp Clock mô phỏng tiếng tích tắc của đồng hồ. Một thể hiện của lớp này chứa thời gian, được lưu trữ trong thuộc tính self. giờ, tự. phút và bản thân. giây. Về cơ bản, chúng ta có thể viết phương thức

x = Clock[24, 45, 17]
6 và phương thức set như thế này

def __init__[self,hours=0, minutes=0, seconds=0]:
        self._hours = hours
        self.__minutes = minutes
        self.__seconds = seconds
    def set[self,hours, minutes, seconds=0]:
        self._hours = hours
        self.__minutes = minutes
        self.__seconds = seconds

Chúng tôi đã quyết định không triển khai điều này vì chúng tôi đã thêm mã bổ sung để kiểm tra tính hợp lý của dữ liệu thời gian vào phương thức đã đặt. Chúng tôi cũng gọi phương thức set từ phương thức

x = Clock[24, 45, 17]
6 vì chúng tôi muốn tránh mã dự phòng. Lớp Đồng hồ hoàn chỉnh

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]

ĐẦU RA

23:59:59
00:00:00

Hãy kiểm tra việc xử lý ngoại lệ của chúng ta bằng cách nhập số float và chuỗi làm đầu vào. Chúng tôi cũng kiểm tra xem điều gì sẽ xảy ra nếu chúng tôi vượt quá giới hạn của các giá trị dự kiến

x = Clock[7.7, 45, 17]

ĐẦU RA

---------------------------------------------------------------------------
TypeError                                 Traceback [most recent call last]
 in 
----> 1x = Clock[7.7,45,17]
 in __init__[self, hours, minutes, seconds]
     14         """
     15 
---> 16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
0

Về cơ bản, hai khả năng có thể tưởng tượng được. Có thể sử dụng "m of C" hoặc "m of A"

Chúng tôi gọi tập lệnh này bằng Python2. 7 [python] và với Python3 [python3] để xem điều gì đang xảy ra

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
1

Chỉ dành cho những ai quan tâm đến Python version2. Để có cùng hành vi kế thừa trong Python2 như trong Python3, mọi lớp phải kế thừa từ "đối tượng" của lớp. Lớp A của chúng tôi không kế thừa từ đối tượng, vì vậy chúng tôi nhận được cái gọi là lớp kiểu cũ, nếu chúng tôi gọi tập lệnh bằng python2. Đa kế thừa với các lớp kiểu cũ được điều chỉnh bởi hai quy tắc. chiều sâu trước rồi từ trái sang phải. Nếu bạn thay đổi dòng tiêu đề của A thành "class A[object]. ", chúng ta sẽ có hành vi giống nhau trong cả hai phiên bản Python

Đào tạo Python trực tiếp

Thưởng thức trang này?

Nhìn thấy. Tổng quan về các khóa học Python trực tiếp

Các khóa học trực tuyến sắp tới

Khóa học nâng cao chuyên sâu

Lập trình hướng đối tượng với Python

đăng ký tại đây

siêu và MRO

Chúng ta đã thấy trong quá trình triển khai vấn đề kim cương trước đây, cách Python "giải quyết" vấn đề, tôi. e. theo thứ tự các lớp cơ sở được duyệt qua. Thứ tự được xác định bởi cái gọi là "Thứ tự giải quyết phương pháp" hay gọi tắt là MRO*

Chúng ta sẽ mở rộng ví dụ trước để mỗi lớp định nghĩa phương thức riêng m

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
2

Hãy áp dụng phương pháp m trên một thể hiện của D. Chúng ta có thể thấy rằng chỉ mã của phương thức m của D sẽ được thực thi. Chúng ta cũng có thể gọi một cách rõ ràng các phương thức m của các lớp khác thông qua tên lớp, như chúng ta đã chứng minh trong phiên Python tương tác sau đây

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
3

ĐẦU RA

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
4

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
5

ĐẦU RA

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
0

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
7

ĐẦU RA

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
8

Bây giờ, hãy giả sử rằng phương thức m của D cũng sẽ thực thi mã của m của B, C và A, khi nó được gọi. Chúng ta có thể thực hiện nó như thế này

""" 
The class Clock is used to simulate a clock.
"""
class Clock[object]:
    def __init__[self, hours, minutes, seconds]:
        """
        The paramaters hours, minutes and seconds have to be 
        integers and must satisfy the following equations:
        0 >> x = Clock[12,59,59]
        >>> print[x]
        12:59:59
        >>> x.tick[]
        >>> print[x]
        13:00:00
        >>> x.tick[]
        >>> print[x]
        13:00:01
        """
        if self.__seconds == 59:
            self.__seconds = 0
            if self.__minutes == 59:
                self.__minutes = 0
                if self._hours == 23:
                    self._hours = 0
                else:
                    self._hours += 1
            else:
                self.__minutes += 1
        else:
            self.__seconds += 1
if __name__ == "__main__":
    x = Clock[23,59,59]
    print[x]
    x.tick[]
    print[x]
    y = str[x]
    print[type[y]]
9

Đầu ra là những gì chúng tôi đã được tìm kiếm

23:59:59
00:00:00

0

ĐẦU RA

23:59:59
00:00:00

1

Nhưng hóa ra một lần nữa mọi thứ lại phức tạp hơn chúng tưởng. Làm thế nào chúng ta có thể đối phó với tình huống, nếu cả m của B và m của C cũng sẽ phải gọi m của A. Trong trường hợp này, chúng ta phải loại bỏ cuộc gọi A. m[tự] từ m trong D. Mã có thể trông như thế này, nhưng vẫn có một lỗi ẩn trong đó

23:59:59
00:00:00

2

Lỗi là phương thức m của A sẽ được gọi hai lần

23:59:59
00:00:00

3

ĐẦU RA

23:59:59
00:00:00

4

Một cách để giải quyết vấn đề này - phải thừa nhận rằng không phải là Pythonic - bao gồm việc chia các phương thức m của B và C thành hai phương thức. Phương thức đầu tiên, được gọi là

x = Clock[24, 45, 17]
8 bao gồm mã cụ thể cho B và C và phương thức khác vẫn được gọi là m, nhưng hiện bao gồm cuộc gọi
x = Clock[24, 45, 17]
9 và cuộc gọi
---------------------------------------------------------------------------
TypeError                                 Traceback [most recent call last]
 in 
----> 1x = Clock[24, 45, 17]
 in __init__[self, hours, minutes, seconds]
     14         """
     15 
---> 16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  1x = Clock[7.7,45,17]
 in __init__[self, hours, minutes, seconds]
     14         """
     15 
---> 16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0  16self.set_Clock[hours, minutes, seconds]
     17 
     18     def set_Clock[self, hours, minutes, seconds]:
 in set_Clock[self, hours, minutes, seconds]
     28             self._hours = hours
     29         else:
---> 30raise TypeError["Hours have to be integers between 0 and 23!"]
     31         if type[minutes] == int and 0 

Chủ Đề