python基礎之繼承派生、組合、介面和抽象類別

來源:互聯網
上載者:User

標籤:read   提示   基類   磁碟   同名   err   調用   school   name   

類的繼承與派生

經典類和新式類

在python3中,所有類預設繼承object,但凡是繼承了object類的子類,以及該子類的子類,都稱為新式類(在python3中所有的類都是新式類)

沒有繼承object類的子類成為經典類(在python2中,沒有繼承object的類,以及它的子類,都是經典類)

1 class People:2     pass3 class Animal:4     pass5 class Student(People,Animal): #People、Animal稱為基類或父類,Student為子類,Student繼承了People和Animal的所有屬性6     pass7 print(Student.__bases__)    #__bases__方法,查看繼承的類的元組8 print(People.__bases__)9 print(Animal.__bases__)

輸出結果:

1 (<class ‘__main__.People‘>, <class ‘__main__.Animal‘>)    #繼承了兩個父類2 (<class ‘object‘>,)    #預設繼承了object類3 (<class ‘object‘>,)

繼承

繼承是為了減少代碼重用的問題,以減少代碼冗餘。

繼承是一種是什麼是什麼的關係,例如老師類是人類,而非老師類是生日類

繼承類樣本:

 1 class People:    #定義父類People 2     def __init__(self, name, age): 3         self.name = name 4         self.age = age 5     def walk(self): 6         print(‘%s is walking‘ %self.name) 7  8 #Teacher類和Student類無任何屬性 9 class Teacher(People):    #Teacher類繼承People類的屬性10     pass11 class Student(People):    #Student類繼承People類的屬性12     pass

引用測試:

 1 t=Teacher(‘bob‘,18)    #執行個體化一個Teacher對象,而非People對象,Student子類同理 2 print(type(t))  3 print(t.name,t.age) 4 print(t.__dict__) 5 t.walk()    #Teacher子類繼承了People的屬性,使得Teacher子類的對象能夠調用到父類的屬性 6  7 輸出結果: 8 <class ‘__main__.Teacher‘> 9 bob 1810 {‘name‘: ‘bob‘, ‘age‘: 18}11 bob is walking

派生

派生是在子類繼承父類的基礎上, 定義子類專屬的屬性,例如Teacher可以有教師等級的劃分、有教學課程的劃分,但是繼承父類People類是沒有等級和課程的劃分的。

樣本:

 1 #定義父類People 2 class People: 3     def __init__(self, name, age,sex): 4         self.name = name 5         self.age = age 6         self.sex=sex 7     def walk(self): 8         print(‘%s is walking‘ % self.name) 9     def test(self):10         print(‘test class from father class %s‘ %self.name)11 #定義Teacher子類12 class Teacher(People):13     school = ‘jialidun‘14     def __init__(self, name, age,sex,level,salary):15         People.__init__(self,name,age,sex)    #繼承父類的初始化內容,執行個體化時候接收的參數name、age、sex會傳給People.__init__16         self.level=level    #派生的專屬屬性17         self.salary=salary    #派生的專屬屬性18     def teach(self):    #派生的專屬屬性19         print(‘%s is teaching‘ %self.name)20     def test(self):    #派生父類的已有屬性,對象在進行屬性引用的時候會優先引用執行個體化過程中用到的類21         People.test(self)22         print(‘from teacher‘)23 #定義Student子類24 class Student(People):25     def __init__(self, name, age,sex,group):26         People.__init__(self, name, age, sex)27         self.group=group28     def study(self):29             print(‘%s is studying‘ %self.name)

測實驗證:

1 t=Teacher(‘natasha‘,18,‘male‘,10,3000) #__init__(t,‘natasha‘,18,‘male‘,10,3000)2 print(Teacher.__bases__)3 print(Teacher.__dict__)4 t.test()

組合

不同於繼承,組合是包含的意思,表示一種什麼有什麼的關係,也是為了減少重複代碼的

樣本:還是People、Teacher和Student的例子,只是加上了一個Birthday生日類

 1 #Birthday類,需要傳入年月日 2 class Birthday: 3     def __init__(self,year,mon,day): 4         self.year=year 5         self.mon=mon 6         self.day=day 7     def tell_birth(self): 8         print(‘出生於<%s>年 <%s>月 <%s>日‘ % (self.year,self.mon,self.day)) 9 #People類,需要接受名字年齡年月日,年月日傳給Birthday類10 class People:11     def __init__(self, name, age, year, mon, day):12         self.name = name13         self.age = age14         #__init__接收的year, mon, day傳給Birthday類15         self.birth = Birthday(year, mon, day)   #包含Birthday類,生日不只是人類才有,其他動物也可以有生日,不同於繼承16     def walk(self):17         print(‘%s is walking‘ % self.name)18 #Teacher類19 class Teacher(People):20     def __init__(self, name, age, year, mon, day,level,salary):21         #__init__接收的name, age, year, mon, day傳給People類22         People.__init__(self,name,age,year,mon,day)23         self.level=level24         self.salary=salary25     def teach(self):26         print(‘%s is teaching‘ %self.name)27 #Student類28 class Student(People):29     def __init__(self, name, age, year, mon, day,group):30         People.__init__(self,name,age,year,mon,day)31         self.group=group32     def study(self):33         print(‘%s is studying‘ %self.name)

測實驗證:

1 t=Teacher(‘hurry‘,18,1990,2,33,10,3000)    #傳入的值為Teacher類接收的值2 print(t.name,t.age)    #對象t的名字和年齡3 print(t.birth)    #輸出的是一個類對象,因為父類People定義的birth屬性就是一個類Birthday4 t.birth.tell_birth()    #查看對象t所繼承的People類的birth屬性(Birthday類)的tell_birth()屬性5 print(t.birth.year)6 print(t.birth.mon)7 print(t.birth.day)

介面和抽象類別

介面

介面是一組功能的入口,要調用某一組功能,需要通過介面來進行調用,而不需要關注這組功能是如何?的,要的只是結果。

在類裡,介面是提取了一群類共同的函數,可以把介面當做一個函數的集合。

python模仿介面樣本:

 1 #模仿Linux內檔案讀寫的介面,Linux不管是文本,還是磁碟還是進程都是通過檔案去實現的,只不過方法不同,但是沒關係 2 class File:    #定義一個介面類,提供read和write方法,但是一定是pass沒有處理過程的,因為功能的實現具體靠的是子類 3     def read(self): #定介面函數read 4         pass 5     def write(self): #定義介面函數write 6         pass 7 #定義子類實現讀寫功能 8 #文字檔的讀寫 9 class Txt(File): #文本,具體實現read和write10     def du(self):     #注意並不是read11         print(‘文本資料的讀取方法‘)12     def xie(self):    #注意並不是write13         print(‘文本資料的寫入方法‘)14 #硬碟資料的讀寫15 class Sata(File): #磁碟,具體實現read和write16     def read(self):17         print(‘硬碟資料的讀取方法‘)18     def write(self):19         print(‘硬碟資料的寫入方法‘)20 #進程資料的讀寫21 class Process(File):22     def read(self):23         print(‘進程資料的讀取方法‘)24     def write(self):25         print(‘進程資料的寫入方法‘)

測實驗證:硬碟和進程一樣,所以製作文本和硬碟的測試即可

硬碟讀寫測試:

1 disk=Sata()    #執行個體化一個硬碟讀寫對象2 disk.read()    #硬碟讀3 disk.write()    #硬碟寫4 5 輸出結果:6 硬碟資料的讀取方法7 硬碟資料的寫入方法

文本讀寫測試:執行後會發現沒有任何輸出,那是因為txt對象實際上訪問的read和write屬性並非子類Txt所提供的屬性,Txt所提供的屬性只是du和xie,但是txt對象有read和write屬性,別忘了Txt類是繼承了父類File的屬性,所以實際上txt對象的read和write屬性是父類File提供的

1 txt=Txt()2 txt.read()3 txt.write()

正確的做法是將Txt類的du和xie方法改成read和write方法,這麼做的意義為歸一化

歸一化,讓使用者無需關心對象的類是什麼,只需要的知道這些對象都具備某些功能就可以了,這極大地降低了使用者的使用難度。

抽象類別

抽象類別的本質上也是類,但是抽象類別只能夠被繼承,不能進行執行個體化,也就是說可以當父類,但是不能產生對象。

抽象類別介於介面和歸一化中間,用於實現介面的歸一化

當子類繼承抽象類別的時候,如果抽象類別定義了抽象方法,那麼子類必須要定義同名的方法。即父類限制:

  1、子類必須要有父類的方法

  2、子類實現的方法必須跟父類的方法的名字一樣

python的抽象類別通過abc模組實現。

介面歸一化樣本:

 1 import abc 2 class File(metaclass=abc.ABCMeta):  #metaclass指的是元類,邊會講,現在只需記住這個詞 3     @abc.abstractmethod     #抽象方法,即一個裝飾器裝飾read屬性 4     def read(self): 5         pass 6     @abc.abstractmethod      #抽象方法,即一個裝飾器裝飾write屬性 7     def write(self): 8         pass 9 # # 當繼承File類時候,如果沒有read和write方法,會提示出錯TypeError: Can‘t instantiate abstract class Txt with abstract methods read, write10 # class Txt(File):11 #     def du(self):12 #         print(‘文本資料的讀取方法‘)13 #     def xie(self):14 #         print(‘文本資料的寫入方法‘)15 #定義子類具體實現文本的讀寫操作16 class Txt(File):17     def read(self):18         print(‘文本資料的讀取方法‘)19     def write(self):20         print(‘文本資料的寫入方法‘)21 #定義子類具體實現硬碟的讀寫操作22 class Sata(File):23     def read(self):24         print(‘硬碟資料的讀取方法‘)25     def write(self):26         print(‘硬碟資料的寫入方法‘)27 #定義子類具體實現進程的讀寫操作28 class Process(File):29     def read(self):30         print(‘進程資料的讀取方法‘)31     def write(self):32         print(‘進程資料的寫入方法‘)

測實驗證:

 1 t=Txt() 2 t.read() 3 t.write() 4 s=Sata() 5 s.read() 6 s.write() 7 輸出結果: 8 文本資料的讀取方法 9 文本資料的寫入方法10 硬碟資料的讀取方法11 硬碟資料的寫入方法

python基礎之繼承派生、組合、介面和抽象類別

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.