Python3 學習筆記 -- 繼承


先上一個比較簡單的單繼承語法。在python3中,基類的構造函數不會被自動調用,需要手動調用,同樣的方法也是這樣,需要手動調用。可以使用類名稱+init方法,也可以使用super語法進行調用。在下面這個例子中,子類繼承了基類的方法和字段。字段會在基類中初始化。

 

class BaseClass:    
    def __init__(self):
        self.name = 'BaseClass'
        print('BaseCalss: Constructor called')
    def getname(self):
        print('BaseCalss: self name equals ' + self.name)
 
class DerivedClass(BaseClass):
    def __init__(self):
        super().__init__()
        print('DerivedClass: Constructor called')
 
if __name__ == '__main__':
    class1 = BaseClass()
    class1.getname()
    
    class2 = DerivedClass()
    class2.getname()

運行結果:

BaseCalss: Constructor called
BaseCalss: self name equals BaseClass
BaseCalss: Constructor called
DerivedClass: Constructor called
BaseCalss: self name equals BaseClass

 

子類也可以overwrite父類的方法,那么父類的方法就不會被調用,除非手動調用:

class BaseClass:    
    def __init__(self):
        self.name = 'BaseClass'
        print('BaseCalss: Constructor called')
    def getname(self):
        print('BaseCalss: self name equals ' + self.name)
 
class DerivedClass(BaseClass):
    def __init__(self):
        super().__init__()
        print('DerivedClass: Constructor called')
    def getname(self):
        print('self.name init value is ' + self.name)
        self.name = 'DerivedClass'
        print('DerivedClass: self name equals ' + self.name)
 
if __name__ == '__main__':
    class1 = BaseClass()
    class1.getname()
    
    class2 = DerivedClass()
    class2.getname()

 

運行結果:

BaseCalss: Constructor called
BaseCalss: self name equals BaseClass
BaseCalss: Constructor called
DerivedClass: Constructor called
self.name init value is BaseClass
DerivedClass: self name equals DerivedClass

 

python不僅僅支持單繼承,還支持多繼承,字段和方法都可以被繼承。在多繼承super()只能代表繼承的第一個父類,所以您在子類的構造函數中,不能單獨使用super().__init__(), 那只是表示調用其中一個基類的構造函數。所以用super就不是那么好用了。還是要用會原來的類名+init方法來調用。

class BaseClass1:
    def __init__(self):
        self.name1 = 'BaseClass1_Name1'
        self.name = 'BaseClass1_Name'
        print('BaseCalss1: Constructor called')
    def getname1(self):
        print('BaseCalss1: self name1 equals ' + self.name1)
    def getname(self):
        print('BaseCalss1: getname called, name equal ' + self.name)
 
class BaseClass2:
    def __init__(self):
        self.name2 = 'BaseClass2_Name2'
        self.name = 'BaseClass2_Name'
        print('BaseClass2: Constructor called')
    def getname2(self):
        print('BaseClass2: self name2 equals ' + self.name2)
    def getname(self):
        print('BaseCalss2: getname called, name equal ' + self.name)
 
class DerivedClass2(BaseClass1, BaseClass2):
    def __init__(self):
        BaseClass1.__init__(self)
        BaseClass2.__init__(self)
        print('DerivedClass: Constructor called')
        
if __name__ == '__main__':
    class1 = BaseClass1()
    class1.getname1()
    
    class2 = BaseClass2()
    class2.getname2()
    
    class3 = DerivedClass2()
    class3.getname1()
    class3.getname2()
    class3.getname()

運行結果:

BaseCalss1: Constructor called
BaseCalss1: self name1 equals BaseClass1_Name1
BaseClass2: Constructor called
BaseClass2: self name2 equals BaseClass2_Name2
BaseCalss1: Constructor called
BaseClass2: Constructor called
DerivedClass: Constructor called
BaseCalss1: self name1 equals BaseClass1_Name1
BaseClass2: self name2 equals BaseClass2_Name2
BaseCalss1: getname called, name equal BaseClass2_Name

 

我們可以看到,當兩個基類有方法重名的時候,python3會按照您繼承類的從左到右的順序查找您調用的方法DerivedClass2(BaseClass1, BaseClass2)。在這個例子中,是先找BaseClass1,然后再找BaseClass2。

如果您的代碼需要多層繼承的話,可以參開多重繼承的 Diamond Problem 問題。

class A1:
    def foo1(self):
        print("Call A1's foo1")
class A2:
    def foo1(self):
        print("Call A2's foo1")
    def foo2(self):
        print("Call A2's foo2")
 
class B1(A1,A2):
    pass
class B2(A1,A2):
    def foo2(self):
        print("Call B2's foo2")
        
class C(B1,B2):
    pass
 
if __name__ == '__main__':
    
    class1 = C()
    class1.foo1()
    class1.foo2()

 

運行結果:

Call A1's foo1
Call B2's foo2

所以對於python3 的多層繼承來說,因為都是新式類,總是從左到右,廣度優先的方式進行。

 

本例子代碼可以從這里下載。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM