python - 多繼承
阿新 • • 發佈:2019-01-03
多繼承
子類擁有一個父類叫做單繼承
子類可以擁有多個父類,並且具有所有父類的屬性和方法
例如:孩子會繼承自己父親和母親的特性
class A: def test(self): print('test 方法') class B: def demo(self): print('demo 方法') class D: def haha(self): print('!!!!!!') class C(A,B,D): # A,B,D都是C的父類 pass c = C() c.test() c.demo() c.haha()
輸出:
test 方法
demo 方法
!!!!!!
多繼承的注意事項:
問題的提出:
如果不同的父類中存在同名的方法,子類物件在呼叫方法時,會呼叫哪一個父類中的方法呢?
父類中方法名相同,會呼叫在子類中最先呼叫的類
(提示:開發時,應儘量避免這種容易產生混淆的情況)
如果父類之間存在同名的屬性或方法,因該儘量避免使用多繼承
例如:
class A: def test(self): print('A----test 方法') def demo(self): print('A----demo 方法') class B: def test(self): print('B----test 方法') def demo(self): print('B----demo 方法') class C(B,A): pass c = C() c.test() c.demo()
輸出:
B----test 方法
B----demo 方法
如何避免屬性同名?
class Parent(object): def __init__(self,name): print('parent的init開始被呼叫') self.name = name print('parent的init結束被呼叫') class Son1(Parent): def __init__(self,name,age): print('Son1的init開始被呼叫') self.age = age Parent.__init__(self,name) # Son1有parent的屬性 print('Son1的init結束被呼叫') class Son2(Parent): def __init__(self,name,gender): print('Son2的init開始被呼叫') self.gender = gender Parent.__init__(self,name) # Son2有parent的屬性 print('Son2的init結束被呼叫') class Grandson(Son1,Son2): def __init__(self,name,age,gender): print('grandson的init開始被呼叫') Son1.__init__(self,name,age) Son2.__init__(self,name,gender) # Grandson有Son1和Son2的屬性 print('grandson的init結束被呼叫') gs = Grandson('grandson',18,'男') print('姓名:',gs.name) print('年齡:',gs.age) print('性別:',gs.gender)
也可以用super()解決多繼承的難題:
新式類:呼叫的順序為廣度優先
舊式類:呼叫順順序為深度優先
super()類:不重複的呼叫父類,解決了鑽石繼承(多繼承)的難題
class Person(object):
def __init__(self):
print('我要好好學習')
def study(self):
print('我要好好學習語言')
class Man(Person):
def __init__(self):
print('我是男的我要好好學習')
def study(self):
print('我要學好數學')
super().study()
class Womam(Person):
def __init__(self):
print('我是女的我要好好學習')
def study(self):
print('我要學好英語')
super().study()
class Son(Man,Womam):
def __init__(self):
print('我是兒子我要好好學習')
def study(self):
print('我要學好化學和物理')
# Womam.study(self)
# Man.study(self)
super().study()
print(Son.mro())
son1 = Son()
son1.study()
輸出:
[<class '__main__.Son'>, <class '__main__.Man'>, <class '__main__.Womam'>, <class '__main__.Person'>, <class 'object'>] # mro順序
我是兒子我要好好學習 # Son 屬性
我要學好化學和物理 # Son 方法
我要學好數學 # Man方法
我要學好英語 # Woman方法
我要好好學習語言 # Person方法
super實現原理:通過c3演算法,生成mro(method resolution order)列表,根據列表中元素順序查詢呼叫
super()不是指父類 而是指以例項化物件為起點的mro序列中的下一個
簡潔點的三個原則就是:
子類在父類前,所有類不重複呼叫,從左到右
下面這段程式很複雜,可以用debug進行除錯。
class A():
def go(self):
print('go A go!')
def stop(self):
print('stop A stop!')
def pause(self):
raise Exception('Not Implemented')
class B(A):
def go(self):
super(B, self).go()
print('go B go!')
class C(A):
def go(self):
super(C, self).go()
print('go C go!')
def stop(self):
super(C, self).stop()
print('stop C stop!')
class D(B,C):
def go(self):
super(D, self).go()
print('go D go!')
def stop(self):
super(D,self).stop()
def pause(self):
print('wait D wait!')
class E(B,C):
pass
print(D.mro())
a = A()
b = B()
c = C()
d = D()
d.go()
d.stop()
d.pause()
e = E()
輸出:
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
go A go!
go C go!
go B go!
go D go!
stop A stop!
stop C stop!
wait D wait!