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