物件導向程式設計之super內建函式的用法
先來看一段程式碼:
定義一個名叫People的父類,又定義了一個叫Teacher的老師類和一個叫Student的學生類
來繼承People的類,並根據這兩個子類例項化出兩個物件s1和t1。
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def birth_info(self):
print("The birth is %s-%s-%s"%(self.year,self.mon,self.day))
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def walk(self):
print("%s is walking"%self.name)
class Teacher(People):
def __init__(self,name,age,year,mon,day,course):
People.__init__(self,name,age)
self.course=course
self.birth=Date(year,mon,day)
def teach(self):
print("%s is teaching"%self.name)
class Student(People):
def __init__(self,name,age,year,mon,day,group):
People.__init__(self,name,age)
self.birth = Date(year, mon, day)
self.group=group
def study(self):
print("%s is studying"%self.name)
t1=Teacher("alex",28,1989,9,2,"python")
s1=Student("jack",22,1995,2,8,"group2")
現在問題來了,假如因為需要,我要修改老師類和學生類的父類People的名字。
這樣一來,在老師類Teacher和學生類Student中繼承的類People也要修改,以及它們
呼叫的init方法的那個父類也要修改名字,太麻煩了有沒有?
這時候就可以使用super()這個內建函式來搞定了。
在python直譯器中檢視幫助資訊:
help(super)
得到如下資訊:
Help on class super in module builtins:
class super(object)
| super() -> same as super(__class__, <first argument>)
| super(type) -> unbound super object
| super(type, obj) -> bound super object; requires isinstance(obj, type)
| super(type, type2) -> bound super object; requires issubclass(type2, type)
super是一個內建函式,加括號就得到一個物件,物件super()加”.”可以直接呼叫父類的init方法。
這個物件在呼叫父類的init時,實際上就是在呼叫父類的繫結方法,所以就不需要在括號里加上self了。
修改後的程式碼如下:
class Date:
def __init__(self,year,mon,day):
self.year=year
self.mon=mon
self.day=day
def birth_info(self):
print("The birth is %s-%s-%s"%(self.year,self.mon,self.day))
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def walk(self):
print("%s is walking"%self.name)
class Teacher(People):
def __init__(self,name,age,year,mon,day,course):
super().__init__(name,age)
self.course=course
self.birth=Date(year,mon,day)
def teach(self):
print("%s is teaching"%self.name)
class Student(People):
def __init__(self,name,age,year,mon,day,group):
super().__init__(name,age)
self.birth = Date(year, mon, day)
self.group=group
def study(self):
print("%s is studying"%self.name)
t1=Teacher("alex",28,1989,9,2,"python")
s1=Student("jack",22,1995,2,8,"group2")
這樣一來,父類的名字改變了,程式碼裡面繼承的父類的init方法的名字也不需要修改了。
python2中,也可以使用super,其呼叫方法為:super(Teacher,self)
使用super()函式時,python會在mro列表中繼續搜尋下一個類。
只要每個重定義的方法統一使用super()並只呼叫它一次,那麼控制流最終會遍歷完整個mro列表。每個方法只會呼叫一次。
使用super呼叫的所有的屬性,都是從mro列表當前的位置往後找,看mro列表的順序就可以看到子類的繼承關係
檢視上面程式碼中Teacher這個子類的mro列表可以使用這個方法:
Teacher.mro()
使用super可以避免使用多重繼承時,子類繼承父類的順序問題。
子類繼承父類的資料屬性和函式屬性時,先執行的先生效,當後面的程式碼與前面的程式碼有衝突時,
後面的程式碼會把前面的程式碼覆蓋掉,不使用super時需要自己解決繼承的順序問題,使用super就可以很好的解決這個問題了。
相關文章
- Day 14 匿名函式 內建函式 物件導向程式設計函式物件程式設計
- JavaScript建構函式,物件導向程式設計JavaScript函式物件程式設計
- JS物件導向程式設計(二):建構函式JS物件程式設計函式
- Golang物件導向程式設計之建構函式【struct&new】Golang物件程式設計函式Struct
- Python - 物件導向程式設計 - super()Python物件程式設計
- javascript物件導向程式設計的建構函式的繼承JavaScript物件程式設計函式繼承
- Javascript物件導向程式設計(二):建構函式的繼承JavaScript物件程式設計函式繼承
- javascript物件導向程式設計的非建構函式的繼承JavaScript物件程式設計函式繼承
- Javascript物件導向程式設計(三):非建構函式的繼承JavaScript物件程式設計函式繼承
- C++物件導向程式設計 類和物件提高篇 建構函式C++物件程式設計函式
- 物件導向與函式程式設計的比較物件函式程式設計
- iOS 開發之 OOA (物件導向分析) & OOD (物件導向設計)& OOP (物件導向程式設計)iOS物件OOP程式設計
- 《JavaScript物件導向精要》之四:建構函式和原型物件JavaScript物件函式原型
- 前端筆記之JavaScript物件導向(二)內建建構函式&相關方法|屬性|運算子&繼承&物件導向前端筆記JavaScript物件函式繼承
- JavaScript設計模式之物件導向程式設計JavaScript設計模式物件程式設計
- Python之物件導向程式設計Python物件程式設計
- Javascript 物件導向中的建構函式和原型物件JavaScript物件函式原型
- 函數語言程式設計 VS 物件導向程式設計函數程式設計物件
- 物件導向程式設計物件程式設計
- 物件導向的程式設計之原型模式物件程式設計原型模式
- python之物件導向程式設計(一)Python物件程式設計
- Scala的物件導向程式設計物件程式設計
- JS物件導向的程式設計JS物件程式設計
- javascript:物件導向的程式設計JavaScript物件程式設計
- [.net 物件導向程式設計基礎] (2) 關於物件導向程式設計物件程式設計
- 十三、物件導向程式設計物件程式設計
- js物件導向程式設計JS物件程式設計
- 程式設計思想 物件導向程式設計物件
- 十六、物件導向程式設計物件程式設計
- perl 物件導向程式設計物件程式設計
- LotusScript物件導向程式設計物件程式設計
- Javascript 物件導向程式設計JavaScript物件程式設計
- 物件導向 vs. 函數語言程式設計物件函數程式設計
- 函數語言程式設計 vs 物件導向程式設計 vs 程式式程式設計的JS演示比較 - DEV函數程式設計物件JSdev
- Python學習之物件導向程式設計Python物件程式設計
- python物件導向程式設計之組合Python物件程式設計
- JS物件導向程式設計(一):物件JS物件程式設計
- 程式導向,物件導向,函式式對同一個問題的思考方式物件函式