zoukankan      html  css  js  c++  java
  • 继承补充

    什么是继承?

      它是一种新建类的方式,继承了一个类,类中的属性和方法就在子类中

      父类就是基类, 子类就是派生类

      拓展: 开发工具IDE: vscode, pycharm, sumlinetext

           开发Java: eclipse, myeclipse, idea

         开发安卓: eclipse+adt,   Androidstudio: 基于idea+adt改的

      新式类: 只要继承了object类,就是新式类,Python3中默认继承object类,python2中,需要显示指定的继承object

      经典类: 没有继承object的类,就是经典类,Python3中没有经典类,Python2中才会有

    class A(object):
        pass
    class B(A):
        pass
    
    
    # 查看类名
    print(B.__name__)
    
    
    输出: B
    
    # 查看父类
    print(B.__bases__)   # B的所有的父类
    
    输出为(<class '__main__.A'>,)
    

      

    二. 属性查找的菱形问题:

    class people
        school = 'peking university'
    
    
    
    
    class Teacher(people):
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Student(people):
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    
    stu1 = Student('bgon', 85, "python")   # 实例化一个对象
    print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的
    
    
    
    # 输出结果为: peking university
    

      如果这样继承的话,那么问题就来了,如何重用父类的属性,属性的查找顺序是什么,又是如何重用父类的方法?

      我们之前说过查找对象顺序是: 先找对象===>类中找===>父类中找===>报错,但是呢,今天不一样,在父类中继承了好几个,也就是多继承,那又是如何去寻找?

    三. 重用父类的方法

    class people
        school = 'peking university'
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    
    
    class Teacher(people):
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Student(people):
        def __init__(self, name, age, couse)
                self.name = name
                self.age = age
                self.couse = couse
    
    
    stu1 = Student('bgon', 85, "python")   # 实例化一个对象
    print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的
    

      上面继承中可以看出,代码出现了冗余,那我们如何重用父类的__init__方法呢,我们先看第一种方法: 指名道姓的使用(跟继承无关)

    class people
        school = 'peking university'
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Teacher(people):
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Student(people):
        def __init__(self, name, age, couse)
                people.__init__(self, age,name)
                self.couse = couse
    

      方式二: 通过super关键字

    class people
        school = 'peking university'
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Teacher(people):
        def __init__(self, name, age, level)
                self.name = name
                self.age = age
                self.level = level
    
    class Student(people):
        def __init__(self, name, age, couse)
                super().__init__(name, age)
                self.couse = couse
    

      super()会按照mro列表拿到父类对象,对象来调用绑定方法, 不需要传递第一个参数(self),所以有__init__(name, age)

    class people
        school = 'peking university'
         def __init__(self, name, age)
                self.name = name
                self.age = agel
    
    class Teacher(people):
        pass
    
    class Student(people):
         pass
    
    stu1 = Student('bgon', 85)   # 实例化一个对象
    print(stu1.school)   # 学生类中并没school这个属性,他在父类中定义的
    

      类实例化会自动调用__init__,如果类中没有,就去父类中去寻找

    多层继承:
    
    class A:
        a = "AAAA"
    pass class B(A): a = "BBBB"
      pass class C(B): a = "CCCC"
    pass class D(C): a = "DDDD
       pass d = D() print(d, a) # 输出为DDDD

      

    多继承:

    class A:
        a = "AAAA"
        pass
    class B:
        a = "BBBB"
      pass
    class C:
        a = "CCCC"
         pass
    class D(A, B, C):
        a = "DDDD
       pass
    
    
    d = D()
    print(d, a)
    

      那上面的查找顺序又是怎样的呢? 首先还是先从自己找起,当D中没有a的值时,先找A,然后依次是,B,C

    继承的菱形问题(显式的都继承一个类,不是object类):

      在新式类和经典类的查找顺序是不一样的, 新式类的查找顺序是广度优先(从左侧开始,,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父往上找,找到菱形的顶点结束(不包括菱形顶点)),经典类的查找顺序是深度优先(从左侧开始,,一直往上找,找到菱形的顶点结束(包括菱形顶点))==>一条道找到底然后再去广度上找

    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__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性   super是严格按照mro列表找
    
    #新式类继承顺序:F->D->B->E->C->A
    #经典类继承顺序:F->D->B->A->E->C
    #python3中统一都是新式类
    #pyhon2中才分新式类与经典类
    

      

    所有的父类都到顶,才叫菱形问题,也就是说有一个总要继承object

    生前无需久睡,死后自会长眠,努力解决生活中遇到的各种问题,不畏将来,勇敢面对,加油,你是最胖的,哈哈哈
  • 相关阅读:
    CentOS LiveCD LiveDVD DVD 等版本的区别
    解决蛋疼的阿里云单CPU使用率的问题。
    软件工程在北航
    Introduction of Team Member
    proxool的配置
    hibernate配置jndi
    dbcp的配置
    绘制图片
    myeclipse搭建svn插件
    svn搭建
  • 原文地址:https://www.cnblogs.com/panshao51km-cn/p/11617984.html
Copyright © 2011-2022 走看看