Python物件導向編程(二)

來源:互聯網
上載者:User
1.繼承與派生

上文我們已經說過,Python中一切皆對象。我們從對象中抽取了共同特徵和技能,得到了類的概念。類與類之間也有共同特徵,我們可以從有共同特徵和技能的類中提取共同的技能和特徵,叫做父類。

比如老師和學生,都有名字,年紀,生日,性別等等,都會走,說話,吃飯。。。我們就可以從老師和學生中總結出來一個‘人’類,稱為父類,那老師和學生就是‘人’類的子類,子類繼承父類,就有了父類的特徵和方法。

繼承是一種什麼‘是’什麼的關係,繼承是一種產生新類的方法,當然目的也是為了減少代碼重用。

繼承的 基本形式是:

class People:    passclass Student(People):#People稱為基類或者父類    pass

在Python中支援多繼承,一個子類可以繼承多個父類

我們可以通過__bases__的方法查看繼承的所有父類,會返回一個元組。 

class People:    passclass Animals:    passclass Student(People,Animals):    passprint(Student.__bases__)#(<class '__main__.People'>, <class '__main__.Animals'>)print(People.__bases__)#(<class 'object'>,)

可以看到,在People父類中,預設也繼承了一個object類,這就是新式類和經典類的區別:
凡是繼承了object類的類及其子類,都稱為新式類,沒有繼承object類的類,稱為經典類。

在Python 3中,預設就是新式類,而在Python2.X中,預設都是是經典類

繼承怎麼減少代碼呢?看例子

class People:    def __init__(self,name,age):        self.name=name        self.age=age    def walk(self):        print('%s is walkig'%self.name)class Teacher(People):    def __init__(self,name,age,level):        People.__init__(self,name,age)        self.level=levelt1=Teacher('zhang',18,10)print(t1.level) #10print(t1.name)  #zhang          子類可以用父類定義的屬性t1.walk()   #zhang is walking   子類無需定義就可以用父類的方法print(issubclass(Teacher,People))   #True查看Teacher類是不是People類的子類

從上面的例子中可以看到,Teacher類繼承了父類People類,但是Teacher又有自己特有的屬性level,子類也可以定義自己專屬的方法,甚至可以和父類的方法重名,但是執行時會以子類定義的為準。

這就叫做派生

2.組合

繼承是解決什麼‘是’什麼的問題,那還有一種情境就是什麼有什麼,比如老師有生日,學生也有生日,生日有年月日這些屬性,如果每個類都寫的話,又是重複代碼。但是又不能讓學生和老師繼承生日類。這時就用到了組合。組合就是解決什麼‘有’什麼的問題。看例子

class Date:    def __init__(self,year,mon,day):        self.year=year        self.mon=mon        self.day=day    def tell_birth(self):        print('出生於%s年%s月%s日'%(self.year,self.mon,self.day))class Teacher:    def __init__(self,name,age,year,mon,day):        self.name=name        self.age=age        self.birth=Date(year,mon,day)t=Teacher('egon',19,2010,10,10)print(t.birth)          #<__main__.Date object at 0x0000017E559380F0>t.birth.tell_birth()    #出生於2010年10月10日

什嗎?嫌參數太多?*args學過吧,你高興就好

 1 class Date: 2     def __init__(self,year,mon,day): 3         self.year=year 4         self.mon=mon 5         self.day=day 6     def tell_birth(self): 7         print('出生於%s年%s月%s日'%(self.year,self.mon,self.day)) 8  9 class Teacher:10     def __init__(self,name,age,*args):11         self.name=name12         self.age=age13         self.birth=Date(*args)14 t=Teacher('egon',19,2010,10,10)15 print(t.birth)          #<__main__.Date object at 0x0000017E559380F0>16 t.birth.tell_birth()    #出生於2010年10月10日
View Code

3.抽象類別與介面

繼承有兩種用途:1.代碼重用,子類繼承父類的方法

        2.聲明某個子類相容於某父類,定義一個介面類Interface,介面類中定義了一些介面名(就是函數名)且並未實現介面的功能,子類繼承介面類,並且實現介面中的功能

需要注意的是,Python中並沒有介面的關鍵字,我們只能是模仿介面的功能
比如在 Python中,一切皆檔案嘛,那程式是檔案,硬體是檔案,文字文件也是檔案,我們知道什麼叫檔案呢,就是能讀能寫,那程式,文字文件這些,都應該有讀和寫的功能,我們來類比一下

class Interface:    def read(self):        pass    def write(self):        pass        class Txt(Interface):    def read(self):        print('文字文件的讀取方式')    def write(self):        print('文字文件的寫入方式')        class Sata(Interface):    def read(self):        print('硬碟檔案的讀取方式')    def write(self):        print('硬碟檔案的寫入方式')class process(Interface):    def read(self):        print('進程資料的讀取方式')    def write(self):        print('進程資料的寫入方式')
View Code

這麼做的意義就是:我們不需要知道子類有什麼具體的方法,既然他們繼承了檔案類,那他們就是檔案,那他們就有讀和寫這兩個功能

父類限制了子類子類必須有read和write這兩個方法,而且名字也必須一樣(當然現在只是我們主觀上的限制,一會我們說完抽象類別,就可以從代碼層級上限制了),這樣就實現了統一,類比了介面的概念,這就是歸一化設計。在歸一化設計中,只要是基於一個介面設計的類,那麼所有的這些類執行個體化出來的對象,在用法上是一樣的

我們再來說一下抽象類別:

Python中的抽象類別需要匯入一個模組來實現。抽象類別只能被繼承,不能被實現

抽象類別的寫法:

import abcclass File(metaclass=abc.ABCMeta):    @abc.abstractmethod    def read(self):        pass    @abc.abstractmethod    def write(self):        pass#父類使用了抽象類別,那子類就必須繼承父類的方法,而且名字也必須一樣#這樣就實現了代碼層級的限制class Txt(File):    def read(self):        print('文字文件的讀取方式')    def write(self):        print('文字文件的寫入方式')

 

4.繼承的實現原理

1)繼承順序:

python支援多繼承,當一個類繼承多個父類時,繼承順序是怎樣的呢?這個順序在新式類和經典類中是不一樣的。

在新式類中,繼承順序是廣度優先,在經典類中是深度優先,舉個栗子:

圖不重要,看內容
在這個圖中,H是子類,H繼承E,F,G,E,F,G,又分別繼承B,C,D,B,C,D,同時繼承A

在新式類中的順序是:H E B F C G D A 

在經典類中的順序是:H E B A F C G D

2)繼承原理:

當我們定義一個類後,Python就會根據上面的繼承規律解析出一個繼承順序的列表(MRO列表),可以通過mro()查看,但是這個方法只有在新式類中才有,經典類沒有

mro

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.