Python day26:繼承

今日內(nèi)容:
1.繼承介紹
2.繼承與抽象
3.屬性查找
4.繼承的實現(xiàn)原理
5.菱形問題
6.繼承原理
7.深度優(yōu)先與廣度優(yōu)先
8.python的mixins機(jī)制

一、繼承介紹
1.繼承:繼承是一種新建類的方式鼎文,新建的類稱之為子類解取,被繼承的類稱為父類吉捶,也成為基類與超類
2.為何要用繼承:子類會遺傳父類的屬性(與方法),所以繼承是解決類與類之間代碼冗余的問題
還記得我們?yōu)槭裁磿x出類嗎,我們學(xué)習(xí)的編程方法叫做面向?qū)ο缶幊掏崃幔皇敲嫦蝾惥幊蹋乔皫滋扉_始學(xué)習(xí)時我們的類是為什么創(chuàng)建出來的呢掷匠?
當(dāng)我們創(chuàng)建對象時滥崩,發(fā)現(xiàn)很多對象都會有相同的特征,如名字讹语,性別钙皮,年齡等,每創(chuàng)建一個對象我們就要寫重復(fù)代碼,所以類是為了減少對象與對象之間代碼冗余的問題
3.如何繼承:

class Parent1:
    pass

class Parent2:
    pass

class Sub1(Parent1):
    pass

class Sub2(Parent1,Parent2):
    pass

print(Sub1.__bases__)
print(Sub2.__bases__)



# 繼承案列:
class OldboyPeople:
    school = "oldboy"


class Student(OldboyPeople):
    def __init__(self,name,age,gender,stud_id,course):
        self.name = name
        self.age = age
        self.gender = gender
        self.stu_id = stud_id
        self.course = course

    def choose(self):
        print('%s 正在選課' %self.name)

class Teacher(OldboyPeople):
    def __init__(self,name,age,gender,salary,level):
        self.name = name
        self.age = age
        self.gender = gender
        self.salary = salary
        self.level = level

    def score(self,stu,num):
        stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
tea1=Teacher("egon",18,'male',2000,10)


print(stu1.school)

二株灸、繼承與抽象
名字很高大上崇摄,其實就是為了幫助我們理解為什么要有父類。抽象的意思慌烧,就是我們從不同的對象總結(jié)相同特點逐抑,創(chuàng)建一個類,之后再根據(jù)類的相同特征再找出一個父類屹蚊,如人可以是一個類厕氨,貓可以是一個類,狗可以是一個類汹粤,我們還可以根據(jù)這三個類總結(jié)一個動物類命斧。這個過程就是抽象的過程。
而當(dāng)我們根據(jù)以上的關(guān)系根據(jù)三個類實例化出對象嘱兼,那么動物類就是人国葬,貓,狗的父類芹壕。

三汇四、屬性查找:有了繼承關(guān)系,對象在查找屬性時踢涌,先從對象自己的dict中找通孽,如果沒有則去子類中找,然后再去父類中找……
因為屬性查找的順序睁壁,所以當(dāng)子類與父類都有同一個方法名(但是功能不同)時背苦,總是會優(yōu)先查找子類中的方法,就產(chǎn)生了一個覆蓋的效果潘明。
若父類不想讓子類調(diào)用自己的方法行剂,可以利用隱藏屬性,加入雙下劃線钳降,這就表示這個方法只能在本類中調(diào)用

# 在子類派生的新方法中重用父類的功能
# 方式一:指名道姓地調(diào)用某一個類的函數(shù)
# 特點:不依賴于繼承關(guān)系
#
class OldboyPeople:
    school = "oldboy"
    #             空對象,"艾利克斯",73,'male'
    def __init__(self,name,age,gender):
        self.name = name
        self.age = age
        self.gender = gender

    def f1(self):
        print('1111111')

class Student(OldboyPeople):
    #            空對象,"艾利克斯",73,'male',1001,"python全棧開放"
    def __init__(self,name,age,gender,stu_id,course):
        OldboyPeople.__init__(self,name,age,gender)  # OldboyPeople.__init__(空對象,"艾利克斯",73,'male')
        self.stu_id = stu_id
        self.course = course


    def choose(self):
        print('%s 正在選課' %self.name)

    def f1(self):
        OldboyPeople.f1(self)
        print("22222")

class Teacher(OldboyPeople):
    def score(self,stu,num):
        stu.num = num


stu1=Student("艾利克斯",73,'male',1001,"python全棧開放")
# tea1=Teacher("egon",18,'male',2000,10)

stu1.f1()

四厚宰、繼承的實現(xiàn)原理
新式類:繼承了Object類的子類以及他的所有子類,都稱為新式類
經(jīng)典類:沒有繼承Object類的任何類都稱為經(jīng)典類
在python3中牲阁,做了處理固阁,所有的類都是新式類。即如果你在定義一個類的時候城菊,沒有繼承其他類备燃,python3會默認(rèn)幫你繼承Object類,在python2中并無此處理,所以python2中既有經(jīng)典類也有新式類凌唬。
若你寫的類想要兼容python2與python3并齐,只要在定義類時,繼承Object就可以了

五、菱形問題
菱形問題:一個子類繼承的多條分支最終匯聚到一個不是Object的類况褪,注意撕贞,菱形問題不是一個好事情,在你的項目中一定要盡可能的避免這個問題
如果繼承關(guān)系為菱形結(jié)構(gòu)测垛,即子類的父類最后繼承了同一個類捏膨,那么屬性的查找方式有兩種:
經(jīng)典類:深度優(yōu)先
新式類:廣度優(yōu)先
深度優(yōu)先演示圖:


image.png

廣度優(yōu)先演示圖:


image.png

C3算法與mro()方法介紹(了解即可)
python到底是如何實現(xiàn)繼承的,對于你定義的每一個類食侮,python會計算出一個方法解析順序(MRO)列表号涯,這個MRO列表就是一個簡單的所有基類的線性順序列表,如:

print(A.mro())  # A.__mro__
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
for i in A.mro():
    print(i)
<class '__main__.A'>
<class '__main__.B'>
<class '__main__.E'>
<class '__main__.C'>
<class '__main__.F'>
<class '__main__.D'>
<class '__main__.G'>
<class 'object'>

六锯七、Pyton Mixins機(jī)制
首先這不是一個語法链快,而更像是一個python程序員之間的約定
Python既然設(shè)計了可以多繼承,那么多繼承一定有他便利的地方眉尸,最了然的就是我們可以繼承多個類域蜗,減少代碼冗余。但是多繼承又容易產(chǎn)生菱形問題噪猾,并且和我們以往的繼承思想有所不同霉祸。
人的世界觀里繼承應(yīng)該是個”is-a”關(guān)系。 比如轎車類之所以可以繼承交通工具類畏妖,是因為基于人的世界觀脉执,我們可以說:轎車是一個(“is-a”)交通工具疼阔,而在人的世界觀里戒劫,一個物品不可能是多種不同的東西,因此多重繼承在人的世界觀里是說不通的婆廊。
但是在我們的程序設(shè)計中迅细,又是可能會出現(xiàn)一個對象卻是需要繼承多個類。如下例子:

'''
民航飛機(jī)淘邻、直升飛機(jī)茵典、轎車都是一個(is-a)交通工具,前兩者都有一個功能
是飛行fly宾舅,但是轎車沒有统阿,所以如下所示我們把飛行功能放到交通工具這個
父類中是不合理的
'''
class Vehicle:  # 交通工具
    def fly(self):
        '''
        飛行功能相應(yīng)的代碼        
        '''
        print("I am flying")


class CivilAircraft(Vehicle):  # 民航飛機(jī)
    pass


class Helicopter(Vehicle):  # 直升飛機(jī)
    pass


class Car(Vehicle):  # 汽車并不會飛,但按照上述繼承關(guān)系筹我,汽車也能飛了
    pass

但是如果民航飛機(jī)和直升機(jī)都各自寫自己的飛行fly方法扶平,又違背了代碼盡可能重用的原則(如果以后飛行工具越來越多,那會重復(fù)代碼將會越來越多)蔬蕊。
?怎么辦结澄???為了盡可能地重用代碼麻献,那就只好在定義出一個飛行器的類们妥,然后讓民航飛機(jī)和直升飛機(jī)同時繼承交通工具以及飛行器兩個父類,這樣就出現(xiàn)了多重繼承勉吻。這時又違背了繼承必須是”is-a”關(guān)系监婶。這個難題該怎么解決虱痕?

Python提供了Mixins機(jī)制纲熏,簡單來說Mixins機(jī)制指的是子類混合(mixin)不同類的功能,而這些類采用統(tǒng)一的命名規(guī)范(例如Mixin后綴)苍息,以此標(biāo)識這些類只是用來混合功能的源譬,并不是用來標(biāo)識子類的從屬"is-a"關(guān)系的集惋,所以Mixins機(jī)制本質(zhì)仍是多繼承,但同樣遵守”is-a”關(guān)系踩娘,如下

class Vehicle:  # 交通工具
    pass


class FlyableMixin:
    def fly(self):
        '''
        飛行功能相應(yīng)的代碼        
        '''
        print("I am flying")


class CivilAircraft(FlyableMixin, Vehicle):  # 民航飛機(jī)
    pass


class Helicopter(FlyableMixin, Vehicle):  # 直升飛機(jī)
    pass


class Car(Vehicle):  # 汽車
    pass

# ps: 采用某種規(guī)范(如命名規(guī)范)來解決具體的問題是python慣用的套路

使用Mixin類實現(xiàn)多重繼承要非常小心
首先它必須表示某一種功能刮刑,而不是某個物品,python 對于mixin類的命名方式一般以 Mixin, able, ible 為后綴
其次它必須責(zé)任單一养渴,如果有多個功能雷绢,那就寫多個Mixin類,一個類可以繼承多個Mixin理卑,為了保證遵循繼承的“is-a”原則翘紊,只能繼承一個標(biāo)識其歸屬含義的父類
然后,它不依賴于子類的實現(xiàn)
最后藐唠,子類即便沒有繼承這個Mixin類帆疟,也照樣可以工作,就是缺少了某個功能宇立。(比如飛機(jī)照樣可以載客踪宠,就是不能飛了)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市妈嘹,隨后出現(xiàn)的幾起案子柳琢,更是在濱河造成了極大的恐慌,老刑警劉巖润脸,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件柬脸,死亡現(xiàn)場離奇詭異,居然都是意外死亡毙驯,警方通過查閱死者的電腦和手機(jī)倒堕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尔苦,“玉大人涩馆,你說我怎么就攤上這事行施。” “怎么了魂那?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵蛾号,是天一觀的道長。 經(jīng)常有香客問我涯雅,道長鲜结,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任活逆,我火速辦了婚禮精刷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蔗候。我一直安慰自己怒允,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布锈遥。 她就那樣靜靜地躺著纫事,像睡著了一般。 火紅的嫁衣襯著肌膚如雪所灸。 梳的紋絲不亂的頭發(fā)上丽惶,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機(jī)與錄音爬立,去河邊找鬼钾唬。 笑死,一個胖子當(dāng)著我的面吹牛侠驯,可吹牛的內(nèi)容都是我干的抡秆。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼陵霉,長吁一口氣:“原來是場噩夢啊……” “哼琅轧!你這毒婦竟也來了伍绳?” 一聲冷哼從身側(cè)響起踊挠,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎冲杀,沒想到半個月后效床,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡权谁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年剩檀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旺芽。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡沪猴,死狀恐怖辐啄,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情运嗜,我是刑警寧澤壶辜,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站担租,受9級特大地震影響砸民,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奋救,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一岭参、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尝艘,春花似錦演侯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隘梨,卻和暖如春程癌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轴猎。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工嵌莉, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捻脖。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓锐峭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親可婶。 傳聞我的和親對象是個殘疾皇子沿癞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348