進擊のpython
多繼承
多繼承?什麼是多繼承?就是繼承多個唄!
這多好理解啊!
怎麼叫多繼承呢?
孫悟空知道吧!
猴子吧!神仙吧!
強行操作是不是就是兩個父類!
那怎麼繼承?
你一個都會,兩個就不會了??
對吧,要學會類比啊!
# -*- coding: utf-8 -*-
# @Time : 2019.07.16
# @Author : 爪爪
# @Url : https://www.cnblogs.com/jevious/
class Shenxian:
print("我是神仙,法力無邊!")
pass
class Monkey:
print("我是猴子,我賊流弊!")
pass
class Sunwukong(Monkey, Shenxian):
pass
Sunwukong()
我是神仙,法力無邊!
我是猴子,我賊流弊!
這時候你就可以發現,我sunwukong這個類
就繼承了shenxian和monkey的屬性
當然,sunwukong也可以繼承他們的方法
# -*- coding: utf-8 -*-
# @Time : 2019.07.17
# @Author : 爪爪
# @Url : https://www.cnblogs.com/jevious/
class Shenxian:
def shen(self):
print("我是神仙,法力無邊!")
pass
class Monkey:
def hou(self):
print('我是猴子,我賊流弊!')
pass
class Sunwukong(Shenxian, Monkey):
def sun(self):
print("齊!天!大!聖!")
pass
s = Sunwukong()
看,當我例項化之後呼叫方法的時候
來自父類的函式是不是也可以被呼叫
繼承順序
看著很簡單哈,但是不僅僅是這樣的哦
你看啊,houzi是不是還可以繼承個動物類?
動物類是不是還可以繼承生物類?
生物類是不是還可以繼承……
總之如果要是擴充來說有好多對吧!
在研究這個問題之前
是不是還應該有個問題沒被解決呢?
就是要是我shenxian類和monkey類裡
都有個eat方法,當我sunwukong呼叫的時候
是用哪個?
# -*- coding: utf-8 -*- # @Time : 2019.07.17 # @Author : 爪爪 # @Url : https://www.cnblogs.com/jevious/ class Shenxian: def shen(self): print("我是神仙,法力無邊!") pass def eat(self): print("神仙吃東西!") class Monkey: def hou(self): print('我是猴子,我賊流弊!') pass def eat(self): print("猴子吃東西!") class Sunwukong(Shenxian, Monkey): def sun(self): print("齊!天!大!聖!") pass s = Sunwukong() s.eat()
從提示可以看出來例項化的eat方法是來自shenxian的
那到底是不是呢?
執行一下!
神仙吃東西!
果然,執行的是shenxian裡面的eat方法
所以說大概就有概念了,這個繼承啊
是有順序的
先繼承shenxian裡面的方法,再繼承monkey的方法
重複的以前面的為準(shenxian在monkey前面)
但是,你以為
這就完事了?
就像我剛才提到的那個問題
如果是那種情況,繼承順序是什麼樣的呢?????
# -*- coding: utf-8 -*- # @Time : 2019.07.17 # @Author : 爪爪 # @Url : https://www.cnblogs.com/jevious/ class Super_shenxian: def eat(self): print("超級神仙吃東西!") pass class Shenxian(Super_shenxian): def shen(self): print("我是神仙,法力無邊!") pass def eat(self): print("神仙吃東西!") class Shengwu: def eat(self): print("生物吃東西") pass class Monkey(Shengwu): def hou(self): print('我是猴子,我賊流弊!') pass def eat(self): print("猴子吃東西!") class Sunwukong(Monkey, Shenxian): def sun(self): print("齊!天!大!聖!") pass s = Sunwukong() s.eat()
在執行之前,我們先來分析一下這個程式的繼承關係
是吧,是這樣的吧!沒問題吧
那按照我們來想的
是不是應該可以有兩種查詢方法
sunwukong⇨monkey⇨shengwu⇨shenxian⇨super_shenxian
這種查詢方法叫 深度優先
sunwukong⇨monkey⇨shenxian⇨shengwu⇨super_shenxian
這種查詢方法叫 廣度優先
那我們的繼承遵循哪種呢?
執行上方程式碼
猴子吃東西!
但是這也不能確定是深度還是廣度
那如果shengwu有eat方法
shenxian也有eat方法
但是monkey沒有eat方法
那我要是執行結果是“神仙吃東西”
是不是就代表著是廣度優先?
同理,我要是執行結果是“生物吃東西”
是不是就代表著是深度優先?
這個邏輯能理解吧
那我們試一下
# -*- coding: utf-8 -*- # @Time : 2019.07.17 # @Author : 爪爪 # @Url : https://www.cnblogs.com/jevious/ class Super_shenxian: def eat(self): print("超級神仙吃東西!") pass class Shenxian(Super_shenxian): def shen(self): print("我是神仙,法力無邊!") pass def eat(self): print("神仙吃東西!") class Shengwu: def eat(self): print("生物吃東西") pass class Monkey(Shengwu): def hou(self): print('我是猴子,我賊流弊!') pass # def eat(self): # print("猴子吃東西!") class Sunwukong(Monkey, Shenxian): def sun(self): print("齊!天!大!聖!") pass s = Sunwukong() s.eat()
執行結果是:
生物吃東西
那說明什麼?說明繼承是深度優先是吧!
邏輯沒問題吧!
你以為???這就結束了???
真◇繼承順序
在python中啊,類的寫法有兩種
經典類:
class A: pass
新式類:
class B(object): pass
而python呢,又有兩種版本 2.x 和 3.x
所以就出現了四種組合情況是吧!
在2.x版本中,經典類採用的是深度優先,新式類採用的是廣度優先
在3.x版本中,無論新式類還是經典類,都是按廣度優先查詢的
在2.x中預設的都是經典類,只有顯示繼承了object才是新式類
在3.x中預設的都是新式類,不必顯示繼承object
等會???????????????
剛才我們們實驗出來了,3.x版本是深度優先啊!
怎麼你現在跟我說是廣度優先???????
kidding me???????????????
別罵人別罵人!聽我
狡辯說啊!
有沒有這種情況?
我的super_shenxian 和 shengwu 的上面還有個爹
shijie!
可以不!
shijie裡面也有eat方法行不
我把houzi的eat取消掉
我再把shengwu的eat取消掉
那我查詢的時候是不是應該繼續找shengwu的父親
也就是shijie!
然後執行shijie裡面的eat是吧
最後列印”世界吃東西“是吧
這是我們們原先的邏輯,沒問題吧!
寫一下行吧
# -*- coding: utf-8 -*- # @Time : 2019.07.17 # @Author : 爪爪 # @Url : https://www.cnblogs.com/jevious/ class Shijie(object): def eat(self): print("世界都在吃東西!") pass class Super_shenxian(Shijie): def eat(self): print("超級神仙吃東西!") pass class Shenxian(Super_shenxian): def eat(self): print("神仙吃東西!") class Shengwu(Shijie): # def eat(self): # print("生物吃東西") pass class Monkey(Shengwu): # def eat(self): # print("猴子吃東西!") pass class Sunwukong(Monkey, Shenxian): def sun(self): print("齊!天!大!聖!") pass s = Sunwukong() s.eat()
你列印出來的是什麼??大聲告訴我!
是不是”世界吃東西“?
不是!
是什麼?
神仙吃東西!
是不是就不是深度優先原則了????
那他到底是什麼優先呢???????
其實好多都在說是廣度優先
但是很明顯,當沒有交集的時候,依照的是的是深度優先
有交集又用的是類廣度有限的演算法
那到底是什麼!!!!!!!!!!!!!
多繼承C3演算法
上面的都算簡單的,來來來,看看這個?
# -*- coding: utf-8 -*- # @Time : 2019.07.17 # @Author : 爪爪 # @Url : https://www.cnblogs.com/jevious/ class A: def test(self): print('from A') class B(A): # def test(self): # print('from B') pass class B2: def test(self): print('from B2') class C(A): def test(self): print('from C') class C2: def test(self): print('from C2') class D(B, B2): # def test(self): # print('from D') pass class E(C, C2): def test(self): print('from E') class F(D, E): # def test(self): # print('from F') pass f1 = F() f1.test()
輸出結果自己列印┗|`O′|┛ 嗷~~
那這個繼承關係是什麼呢????
來,我的好兄弟
告訴我,tell me
這是什麼順序???
廣度???
深度???
其實都不是,這是一個叫C3演算法來計算繼承順序的
不打算說,因為我也不會
所以你要是想研究
你就去難為百度去,行不?
那我就想知道繼承順序怎麼辦??
好說,程式設計師都給你寫出來方法了
print(F.__mro__) # 列印類的繼承順序
你列印出來的就是繼承順序!
(<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class '__main__.B2'>, <class '__main__.C2'>, <class 'object'>)
都有方法了,你還自己找???
那你可真是個小機靈!
其實這都是很極端的
真正寫的哪有這麼繼承的?
頂多就寫到shijie那種就可以了
寫成這樣的
不是天才,就是瘋子!