zoukankan      html  css  js  c++  java
  • python面向对象之继承

    2. 继承

    继承的第一个作用

    第一阶段:继承的作用

    class Animal(object):
        def run(self):
            print("Animal is running")
    
    class Dog(Animal):
        pass
    
    class Cat(Animal):
        pass
    
    dog = Dog()
    cat = Cat()
    
    dog.run()
    cat.run()
    
    Animal is running
    Animal is running
    

    上面Animal就是父类,子类就是Dog和Cat,因为Dog和Cat继承了Animal,子类会拥有父类的所有方法。

    总结:

    ​ 1. 当子类继承父类后,子类就会拥有父类的所有方法

    继承的第二个作用:子类重写方法后,优先调用子类方法

    第二阶段:当子类继承父类后,子类写了一个run方法,父类也写了一个run方法,子类调用run方法时,应该调用父类的run还是子类的?

    # 子类继承父类的方法
    class Animal(object):
        def run(self):
            print("Animal is running")
    
    class Dog(Animal):
        def run(self):
            print("Dog is running")
    
    class Cat(Animal):
        def run(self):
            print("Cat is running")
    
    dog = Dog()
    cat = Cat()
    
    # 调用方法
    dog.run()
    cat.run()
    
    Dog is running
    Cat is running
    

    由此可以看出,优先调用子类的方法

    总结:

    ​ 1. 当子类拥有和父类相同的方法时,优先调用子类的方法。

    继承的第三个作用:类的派生

    class person(object):
        def __init__(self, weight):
            self.weight = weight
    
        def eat(self):
            print("正在吃东西")
    
    
    class Student(person):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
    a = Student('plf', 18, '男')
    a.eat()
    print(a.name, a.age, a.sex)
    
    正在吃东西
    plf 18 男
    

    对于以上的代码,提出一个疑问:既然Student类继承了person类,那么Student初始化的对象就拥有了person类的方法,但是对应person的属性weight,Student似乎没有继承到,那么我们如何在初始化Student对象时,拥有父类的weight属性?同时拥有不同于父类的属性?

    class person(object):
        def __init__(self,weight):
            self.weight = weight
    
    class Student(person):
        def __init__(self,name,age,sex,weight):
            self.name = name
            self.age = age
            self.sex = sex
            super().__init__(weight)		# 调用了父类的__init__方法,并将weight传给了person
    
    
    a = Student('plf',18,'男',140)
    print(a.name,a.age,a.sex,a.weight)
    

    因此想要得到父类的属性,必须要在子类的初始化方法中(__init__函数)中调用父类的方法:super()._init_(args,*kwargs) 这样就能拿到父类的属性并赋值 最后变成自己的属性,同时子类有不同于父类的属性。子类继承父类,子类有父类的属性,且子类有不同于父类的属性,那么这一过程我们成为类的派生

    经典类和新式类

    什么是经典类 什么事是新式类

    '''
    Python 2 当中类分为新式类和经典类 
    Python 3中全部叫新式类  
    python 2中如果有继承父类是object 就是新式类,继承其他类不算,但是如果继承其他类,其他类有其他了object 那就是新式类
    '''
    
    # 经典类
    class 类名:
        pass
    
    # 新式类
    class 类名(object):
        pass
    

    经典类的继承特点:深度优先

    新式类的继承特点:广度优先

    使用代码证明

    class G(object):
        def test(self):
            print('from G')
    
    class E(G):
        def test(self):
            print('from E')
    
    class F(G):
        def test(self):
            print('from F')
    
    class B(E):
        def test(self):
            print('from B')
    
    class C(F):
        def test(self):
            print('from C')
    
    class D(G):
        def test(self):
        	print('from D')
           
    class A(B,C,D):
        def test(self):
            print('from A')
    a=A()
    a.test()
    print(A.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
    
    #新式类继承顺序:A->B->E->C->F->D->G
    #经典类继承顺序:A->B->E->G->C->F->D
    
    #python3中统一都是新式类
    #pyhon2中才分新式类与经典类
    
    from A
    (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
    

    继承原理(python如何实现的继承)python2中没有_mro_

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

    >>> A.mro() #等同于A.__mro__
    (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
    

    为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。
    而这个MRO列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

  • 相关阅读:
    java 多个设备,锁定先后顺序
    使用个推的时候出现Installation error: INSTALL_FAILED_DUPLICATE_PERMISSION
    android 开发-设置控件/view的水平方向翻转
    IIS8中 出现ashx 401:未授权,uploadify上传文件失败
    No Launcher activity found!
    activiti工作流之Eclipse的Eclipse BPMN 2.0 Designer无法安装或者(安装后无法重复打开*.bpmn)
    android Ant 打包
    andorid 直接解压后的xml的解密
    获取当前运行的类名或者方法
    http断点下载客户端和服务端
  • 原文地址:https://www.cnblogs.com/plf-Jack/p/11052958.html
Copyright © 2011-2022 走看看