繼承,多型
阿新 • • 發佈:2021-12-06
面向物件的三大特徵:
1.封裝:就是把資料與功能都整合到一起。針對封裝到物件或者類中的屬性,可以嚴格控制對它們的訪問
2.繼承:繼承是一種建立新類的方式,在python中,新建的類可以繼承一個或多個父類,新建的類可以稱為子類或派生類,父類又可以稱為基類或超類
3.多型:多型指的是一類事物有多種形態,比如動物有多種形態:貓、狗、豬
繼承與抽象
通過類的內建屬性__bases__可以檢視類繼承的所有父類
子類可以繼承父類所有的屬性,因而繼承可以用來解決類與類之間的程式碼重用性問題
class People: school='清華大學' def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age class Student(People): def choose(self): print('%s is choosing a course' %self.name) class Teacher(People): def teach(self): print('%s is teaching' %self.name) stu=Student('ldb','male',18) tea=Teacher('jason','male',20) stu.choose() print(stu.school) tea.teach() print(tea.school)
屬性查詢
有了繼承關係,物件在查詢屬性時,先從物件自己的__dict__中找,如果沒有則去子類中找,然後再去父類中找
class Foo: def f1(self): print('Foo.f1') def f2(self): print('Foo.f2') self.f1() class Bar(Foo): def f1(self):print('Bar.f1') b=Bar() b.f2() # Foo.f2 # Bar.f1
父類如果不想讓子類覆蓋自己的方法,可以採用雙下劃線開頭的方式將方法設定為私有的
class Foo: def __f1(self): # 變形為_Foo__f1 print('Foo.f1') def f2(self): print('Foo.f2') # 變形為self._Foo__f1,因而只會呼叫自己所在的類中的方法 self.__f1() class Bar(Foo): def __f1(self): # 變形為_Bar__f1 print('Bar.f1') b=Bar() b.f2() # 在父類中找到f2方法,進而呼叫b._Foo_f1()方法,同樣是在父類中找到該方法 # Foo.f2 # Foo.f1
繼承原理
python會在mro列表上從左到又開始查詢基類,直到找到第一個匹配這個屬性的類為止
1.子類會先於父類被檢查
2.多個父類會根據它們在列表中的順序被檢查
3.如果對下一個類存在兩個合法的選擇,選擇第一個父類
class A(object): def test(self): print('from A') class B(A): def test(self): print('from B') class C(A): def test(self): print('from C') class D(B, C): pass obj = D() obj.test() # 結果為:from B print(D.mro()) # 新式類內建了mro方法可以檢視線性列表的內容,經典類沒有該內建方法 # [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
多型與多型性
多型性指的是可以在不用考慮物件具體型別的情況下而直接使用物件,這就需要在設計時,把物件的使用方法統一成一種:列如,動物肯定有talk方法,於是我們可以不用它們具體是什麼型別的動物,而直接使用