一.繼承的實現原理python
1.繼承順序ide
1.1單獨分叉線路:經典類與新式類依次從左到右,深度優先函數
1.2多條重合線路:經典類一路到頭,深度優先;新式類,廣度優先。<參考MRO列表,僅在新式類有>工具
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): def test(self): print('from D') class E(C): def test(self): print('from E') class F(D,E): # def test(self): # print('from F') pass f1=F() f1.test() print(F.__mro__) #只有新式纔有這個屬性能夠查看線性列表,經典類沒有這個屬性 #新式類繼承順序:F->D->B->E->C->A #經典類繼承順序:F->D->B->A->E->C #python3中統一都是新式類 #pyhon2中才分新式類與經典類
2.SUPER方法的應用<使用super調用的全部屬性,都是從MRO列表當前的位置日後找,千萬不要經過看代碼去找繼承關係,必定要看MRO列表>spa
子類調用父類的方法:3d
super()---->是一個對象,能夠查看code
方法一:對象
class Vehicle: #定義交通工具類 Country='China' def __init__(self,name,speed,load,power): self.name=name self.speed=speed self.load=load self.power=power def run(self): print('開動啦...') class Subway(Vehicle): #地鐵 def __init__(self,name,speed,load,power,line): Vehicle.__init__(self,name,speed,load,power) self.line=line def run(self): print('地鐵%s號線歡迎您' %self.line) Vehicle.run(self) line13=Subway('中國地鐵','180m/s','1000人/箱','電',13) line13.run()
方法二:blog
class People: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def foo(self): print('from parent') class Teacher(People): def __init__(self,name,age,sex,salary,level): # People.__init__(self,name,age,sex) #指名道姓地調用People類的__init__函數 #在python3中 super().__init__(name,age,sex) #調用父類的__init__的功能,實際上用的是綁定方法 #在python2中 # super(Teacher,self).__init__(name,age,sex) self.salary=salary self.level=level def foo(self): super().foo() print('from child') t=Teacher('egon',18,'male',3000,10) # print(t.name,t.age,t.sex,t.salary,t.level) t.foo()
3.訪問限制繼承
若是要讓內部屬性不被外部訪問,能夠把屬性的名稱前加上兩個下劃線__
,在Python中,實例的變量名若是以__
開頭,就變成了一個私有變量(private),只有內部能夠訪問,外部不能訪問。
具體參考博客:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318650247930b1b21d7d3c64fe38c4b5a80d4469ad7000
4.property的使用
property裝飾器,把裝飾函數假裝成一個名詞屬性。
class People: def __init__(self, name, weight, height): self.name = name self.weight = weight self.height = height # @property def bmi(self): return self.weight / (self.height ** 2) f = People('egon', 70, 1.80) f.height=1.82 print(f.bmi()) #不加裝飾器 #若是沒有@property裝飾器的話,調用函數屬性就得f.bmi(),這樣的接口給人一種明顯的執行程序代碼痕跡,而用 #該裝飾器則直接調用f.bmi,更加方便客戶的使用。 # print(f.bmi) #加裝飾器後
與裝飾器property連用的setter,deleter.
class People: def __init__(self,name,age,sex,height,weight): self.__name=name self.__age=age #此處都是私有屬性,因此須要開放接口來讓對象查看屬性,所以纔會用到相應的裝飾器去修改和刪除屬性。 self.__sex=sex self.__height=height self.__weight=weight def tell_info(self): print(''' 姓名:%s 年齡:%s 性別:%s 高度:%scm 體重:%skg '''%(self.__name,self.__age,self.__sex,self.__height,self.__weight)) @property def name(self): #被property裝飾器裝飾後,能夠直接調用name return self.__name @name.setter ##此處的name就是加上property裝飾器後的name,該name.setter裝飾器爲了修改屬性. def name(self,value): if not isinstance(value,str): raise TypeError('字符串格式') self.__name=value return self.__name @name.deleter ##此處的name就是加上property裝飾器後的name,該name.deleter裝飾器爲了刪除屬性. def name(self): del self.__name @property def bmi(self): return self.__weight /(self.__height^2) p1=People('egon',18,'male',170,60) p1.tell_info() print(p1.name) p1.name='hason' #利用name.setter接口修改屬性 del p1.name #利用name.deleter接口刪除屬性