Python面向?qū)ο?繼承

繼承介紹

繼承指的是類與類之間的關(guān)系,是一種什么是什么的關(guān)系哮洽,功能之一就是用來解決代碼重用問題打却。
繼承是一種創(chuàng)建新類的方式杉适,在python中,新建的類可以繼承一個或多個父類柳击,父類又可稱為基類或超類猿推,新建的類稱為派生類或子類

python 中分為單繼承和多繼承

python中類可以繼承多個類.

class ParentClass1: #定義父類
    pass

class ParentClass2: #定義父類
    pass

class SubClass1(ParentClass1): #單繼承,基類是ParentClass1捌肴,派生類是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2):  # python支持多繼承蹬叭,用逗號分隔開多個繼承的類
    pass

查看繼承的類:

res=SubClass2.__bases__
print(res)
#__base__只查看從左到右繼承的第一個子類,__bases__則是查看所有繼承的父類

輸出:
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

經(jīng)典類和新式類

1.只有在python2中才分新式類和經(jīng)典類状知,python3中統(tǒng)一都是新式類
2.在python2中秽五,沒有顯式的繼承object類的類,以及該類的子類饥悴,都是經(jīng)典類
3.在python2中筝蚕,顯式地聲明繼承object的類,以及該類的子類铺坞,都是新式類
3.在python3中起宽,無論是否繼承object,都默認(rèn)繼承object济榨,即python3中所有類均為新式類

提示:如果沒有指定基類坯沪,python的類會默認(rèn)繼承object類,object是所有python類的基類擒滑,它提供了一些常見方法(如str)的實(shí)現(xiàn)腐晾。

res=ParentClass1.__bases__
print(res)
# 輸出:
(<class 'object'>,)

在開發(fā)程序的過程中,如果我們定義了一個類A丐一,然后又想新建立另外一個類B藻糖,但是類B的大部分內(nèi)容與類A的相同時

我們不可能從頭開始寫一個類B,這就用到了類的繼承的概念库车。

通過繼承的方式新建類B巨柒,讓B繼承A,B會‘遺傳’A的所有屬性(數(shù)據(jù)屬性和函數(shù)屬性)柠衍,實(shí)現(xiàn)代碼重用
在不依賴?yán)^承屬性的情況下,子類在調(diào)用父類的屬性時,可以直接通過函數(shù)調(diào)用的方式調(diào)用父類的屬性:

class ParentClass: #定義父類
    def __init__(self,name,age):
        self.name=name
        self.age=age
class SubClass(ParentClass): 
    def __init__(self,name,age,hobby,title):
        ParentClass.__init__(self,name,age) # 直接以函數(shù)的方式調(diào)用父類的屬性
        self.hobby=hobby
        self.title=title

obj=SubClass('tom',22,'reading','Student')
print(obj.__dict__)

注意:類的屬性引用洋满,會先從實(shí)例中找,然后去類中找,然后再去父類中找...直到最頂級的父類珍坊。

組合

組合指的是牺勾,在一個類中以另外一個類的對象作為數(shù)據(jù)屬性,稱為類的組合
組合與繼承都是有效地利用已有類的資源的重要方式阵漏。但是二者的概念和使用場景皆不同:

1.繼承的方式

通過繼承建立了派生類與基類之間的關(guān)系驻民,它是一種'是'的關(guān)系翻具,比如白馬是馬,人是動物回还。

當(dāng)類之間有很多相同的功能裆泳,提取這些共同的功能做成基類,用繼承比較好懦趋,比如老師是人,學(xué)生是人

2.組合的方式

用組合的方式建立了類與組合的類之間的關(guān)系疹味,它是一種‘有’的關(guān)系,比如教授有生日仅叫,教授教python和linux課程,教授有學(xué)生s1糙捺、s2诫咱、s3...

示例:

# coding=utf-8

class People:
    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

class Course:
    def __init__(self,name,period,price):
        self.name=name
        self.period=period
        self.price=price
    def tell_info(self):
        print('%s %s %s' %(self.name,self.period,self.price))

class Teacher(People):
    def __init__(self,name,age,sex,job_title):
        People.__init__(self,name,age,sex)
        self.job_title=job_title
        self.course=[]
        self.students=[]


class Student(People):
    def __init__(self,name,age,sex):
        People.__init__(self,name,age,sex)
        self.course=[]


egon=Teacher('egon',18,'male','advance')
s1=Student('bob',18,'female')

python=Course('python','3mons',3000.0)
linux=Course('linux','3mons',3000.0)

#為老師egon和學(xué)生s1添加課程
egon.course.append(python)
egon.course.append(linux)
s1.course.append(python)

#為老師egon添加學(xué)生s1
egon.students.append(s1)


#使用
for obj in egon.course:
    obj.tell_info()
print(egon.__dict__)

輸出結(jié)果:

python 3mons 3000.0
linux 3mons 3000.0
{'name': 'egon', 'age': 18, 'sex': 'male', 'job_title': 'advance', 'course': [<__main__.Course object at 0x000000410AF46CC0>, <__main__.Course object at 0x000000410AF46CF8>], 'students': [<__main__.Student object at 0x000000410AF46C88>]}

繼承實(shí)現(xiàn)的原理

1、繼承順序
* python 類可以繼承多個類洪灯,java和C#中則只能繼承一個類
* Python 的類如果繼承了多個類坎缭,那么其查找父類的順序有兩種:深度優(yōu)先廣度優(yōu)先
* 當(dāng)類是經(jīng)典類時,多繼承情況下签钩,會按照深度優(yōu)先的方式查找
* 當(dāng)類是新式類時掏呼,多繼承情況下,會按照廣度優(yōu)先的方式查找
推薦使用新式類铅檩,如果當(dāng)前類或者父類繼承了object類憎夷,那么該類便是一個新式類,否則便是經(jīng)典類昧旨。(經(jīng)典類之存在于python2中)

2拾给、繼承原理(python如何實(shí)現(xiàn)的繼承)
python實(shí)現(xiàn)繼承的原理是: 對于定義的每一個類,python都會計(jì)算出一個方法解析順序(MRO)列表兔沃,這個MRO列表就是一個簡單的所有基類的線性順序表蒋得。

class A:
    pass

class B(A):
    pass

class C:
    pass

class D(C,B):
    pass

obj=D()
print(D.mro())

# 輸出列表:
[<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]

為了實(shí)現(xiàn)繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止。
而這個MRO列表的構(gòu)造是通過一個C3線性化算法來實(shí)現(xiàn)的乒疏。我們不去深究這個算法的數(shù)學(xué)原理,它實(shí)際上就是合并所有父類的MRO列表并遵循如下三條準(zhǔn)則:

  • 子類會先于父類被檢查
  • 多個父類會根據(jù)它們在列表中的順序被檢查
  • 如果對下一個類存在兩個合法的選擇,選擇第一個父類

子類中調(diào)用父類的方法

1额衙、通過指定父類方法名的方式去調(diào)用。(不利用繼承的屬性)
2怕吴、通過使用super()

class Subway(Vehicle): #地鐵
    def __init__(self,name,speed,load,power,line):
        #super(Subway,self) 就相當(dāng)于實(shí)例本身, 在python3中super()等同于super(Subway,self)
        super().__init__(name,speed,load,power)   # 調(diào)用父類的init方法.
        self.line=line

注意:
當(dāng)你使用super()函數(shù)時,Python會在MRO列表上繼續(xù)搜索下一個類入偷。只要每個重定義的方法統(tǒng)一使用super()并只調(diào)用它一次,那么控制流最終會遍歷完整個MRO列表,每個方法也只會被調(diào)用一次(注意注意注意:使用super調(diào)用的所有屬性,都是從MRO列表當(dāng)前的位置往后找械哟,千萬不要通過看代碼去找繼承關(guān)系疏之,一定要看MRO列表)

綁定方法與非綁定方法

類中的函數(shù)可以定義為兩大類,一種是綁定方法暇咆,另一種是非綁定方法锋爪。

1丙曙、綁定方法:綁定給誰,誰來調(diào)用就自動將它本身當(dāng)作第一個參數(shù)傳入:
  - 綁定到類的方法:用classmethod裝飾器裝飾的方法其骄。
為類量身定制亏镰,自動將類當(dāng)作第一個參數(shù)傳入。(其實(shí)對象也可調(diào)用拯爽,但仍將類當(dāng)作第一個參數(shù)傳入)
  - 綁定到對象的方法:沒有被任何裝飾器裝飾的方法索抓。、
為對象量身定制對象毯炮,自動將對象當(dāng)作第一個參數(shù)傳入(屬于類的函數(shù)逼肯,類可以調(diào)用,但是必須按照函數(shù)的規(guī)則來桃煎,沒有自動傳值那么一說)

2篮幢、 非綁定方法:用staticmethod裝飾器裝飾的方法
- 不與類或?qū)ο蠼壎ǎ惡蛯ο蠖伎梢哉{(diào)用为迈,但是沒有自動傳值那么一說三椿。就是一個普通工具而已。在非綁定方法中不需要(不會自動傳值)傳入對象和類葫辐,只是執(zhí)行函數(shù)功能搜锰。

 > 注意:與綁定到對象方法區(qū)分開,在類中直接定義的函數(shù)耿战,沒有被任何裝飾器裝飾的纽乱,都是綁定到對象的方法,可不是普通函數(shù)昆箕,對象調(diào)用該方法會自動傳值鸦列,而staticmethod裝飾的方法,不管誰來調(diào)用鹏倘,都沒有自動傳值一說薯嗤。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市纤泵,隨后出現(xiàn)的幾起案子觉增,更是在濱河造成了極大的恐慌灵巧,老刑警劉巖斩萌,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件许师,死亡現(xiàn)場離奇詭異,居然都是意外死亡公荧,警方通過查閱死者的電腦和手機(jī)带射,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來循狰,“玉大人窟社,你說我怎么就攤上這事券勺。” “怎么了灿里?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵关炼,是天一觀的道長。 經(jīng)常有香客問我匣吊,道長儒拂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任色鸳,我火速辦了婚禮社痛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缕碎。我一直安慰自己褥影,他們只是感情好池户,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布咏雌。 她就那樣靜靜地躺著,像睡著了一般校焦。 火紅的嫁衣襯著肌膚如雪赊抖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天寨典,我揣著相機(jī)與錄音氛雪,去河邊找鬼。 笑死耸成,一個胖子當(dāng)著我的面吹牛报亩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播井氢,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼弦追,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了花竞?” 一聲冷哼從身側(cè)響起劲件,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎约急,沒想到半個月后零远,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厌蔽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年牵辣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奴饮。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡服猪,死狀恐怖供填,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罢猪,我是刑警寧澤近她,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站膳帕,受9級特大地震影響粘捎,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜危彩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一攒磨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧汤徽,春花似錦娩缰、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至完疫,卻和暖如春泰鸡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背壳鹤。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工盛龄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芳誓。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓余舶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親锹淌。 傳聞我的和親對象是個殘疾皇子匿值,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容