zoukankan      html  css  js  c++  java
  • 继承的实现原理

    一.继承的实现原理

      1.继承顺序

        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列表>

      子类调用父类的方法:

      super()---->是一个对象,可以查看

    方法一:

    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

    方法二:

    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
  • 相关阅读:
    TP5之自定义分页样式
    使用ajax方法实现form表单的提交
    H5页面唤起手机拨打电话(拨号)
    php开启openssl扩展
    tp5 加载 extend 类库的方法 (有命名空间和没有命名空间的调用)【转】
    PHP 返回13位时间戳
    thinkphp5 view_path 配置,进行模板分离
    html2canvas 截图不完整 图片缺失问题
    PHP把JSON转换成数组
    tp5怎么隐藏默认模块名啊
  • 原文地址:https://www.cnblogs.com/junxiansheng/p/7122944.html
Copyright © 2011-2022 走看看