繼承
通過__init__類構造方法我們可以看出,我們定義出來的蓋倫類和瑞文類存在代碼冗余的現象,而我們寫程序,最好是以簡潔為目的。如果兩個程序都能達到相同的目標,一個五百行代碼,而另一個只有三百行代碼,毫無疑問我們選擇后者。而且這也很方便我們查閱修改。
所謂繼承,就是重用現有類的功能,并在此基礎上進行擴展,將相關類的共性進行抽象、統一概念,隔離變化。
小明:“不會講話你就多講點。”
簡單地說,在python中,新建的類可以繼承一個或者多個類。父類又可以稱為基類或者超類,新建的類稱為派生類或者子類。
簡單地說,在python中,新建的類可以繼承一個或者多個類。父類又可以稱為基類或者超類,新建的類稱為派生類或者子類。
繼續昨天的蓋倫類和瑞文類:
繼承的原理(了解)
那么Python到底是如何實現繼承的呢?
對于你定義的每一個類,python會計算出一個方法解析順序(MRO)列表,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的為止。而這個MRO列表的構造是通過一個C3線性化算法來實現的。我們不去深究這個算法的數學原理,只需要知道C3算法計算出來的列表,我找屬性應該遵循什么樣的原則:1、子類會先于父類被檢查;
2、多個父類會根據它們在MRO列表中的順序被檢查;3、如果下一個類存在兩個合法的選擇(父類里面有重名的)選擇第一個父類。
Python當中這個列表的產生,決定了你屬性查找的方式,這個查找的方式分成兩種:
深度優先(先深入繼承樹左側查找,然后再返回,開始查找右側)和廣度優先(先從左到右水平方向上查找,最后再深入繼承樹右側查找)。本質查找還是按照MRO列表,深度優先和廣度優先的區別就是排列方式不一樣。
在Python中類是分為兩種的,新式類和經典類。這個區分只有pyhon2中才有,在python3里面已經沒有經典類一說,都是新式類。
那么到底什么是新式類、經典類?
python2才有新式類和經典類的概念(繼承了object的類就是新式類,反之就是經典類)。python3統一都是新式類,也就是都繼承了object。
小明:“那個,那個,那個什么object的玩意兒是什么東西?”
Toranto:“我也不知道...”
小明:“來,吃藥。”
在Python2中,默認都是經典類,只有顯示繼承了object的才是新式類:
在Python3中,取消了經典類,默認都是新式類,并且新式類不需要顯示繼承object對象。如下,這三種寫法都可以,無區別:
多態
我們都知道,在python中,當一個變量被多次賦值的時候,它的傳達結果會表現為最后一次賦值,這是很典型的弱語言。
我們先后調用了Dog和Cat中的eat方法,a被先后賦值為“吃骨頭”,“吃魚”,但這并不是多態。
類的多態特性,需要滿足以下兩個條件:
1、繼承:多態一定是發生在父類和子類之間;
2、重寫:子類重寫了父類的方法。
可以看到,Dog和Cat都繼承自Animal類,且各自都重寫了父類eat()方法。從運行結果可以看出,同一變量 a 在執行同一個 say() 方法時,由于 a 實際表示不同的類實例對象,因此 a.say() 調用的并不是同一個類中的 say() 方法,這就是多態。
換句話說,子類一旦重新定義了自己的屬性或方法且與父類重名,那么調用新增的屬性或方法時,就以自己為準了。
但有時候,在多態形成之后,我們又需要重新調用父類的同名方法時,我們有兩個選擇:
方法一:“指名道姓”地調用某個類的功能(函數)。
方法二:super(),調用super()會得到一個特殊的對象,該對象專門用來引用父類的屬性。
審核編輯:劉清
-
算法
+關注
關注
23文章
4601瀏覽量
92677 -
python
+關注
關注
56文章
4783瀏覽量
84474
發布評論請先 登錄
相關推薦
評論