繼承的實現原理

一.繼承的實現原理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中才分新式類與經典類
View Code

  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()
View Code

方法二: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()
View Code

  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)  #加裝飾器後
View Code

  與裝飾器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接口刪除屬性
View Code
相關文章
相關標籤/搜索