zoukankan      html  css  js  c++  java
  • 继承&&新式类&&经典类

    一、新式类和经典类

    经典类:python2中有继承类

    新式类:python3中都是新式类

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

    2. 父类/基类

    3. 子类/派生类

    4. 新式类:只要继承了object类,在python3中,默认继承object类。

      • python3中,默认继承继承object类
      • python2中,需要显示的指定继承object
    5. 经典类:没有继承object的类,就是经典类

      • python3中没有经典类,都是新式类
      • python中有经典类
    6. 在python3中都是新式类

      class A:  # 新式类:默认继承object,相当于:class A(object)
          pass
      
    7. 在python2中

      class A:  #经典类,没有继承
          pass
      
      class A(object): # 相当于python3中的新式类
          pass
      

    1.1 继承

    class A:
        pass
    class C(A):  # C继承了A这个类
        pass
    
    class A:
        pass
    class B:
        pass
    class C(A,B):  # C继承了A,B这俩个类
        pass
    
    

    1.2类中的其他属性

    class A:
        pass
    class B:
        pass
    class C(A,B):  # C继承了A,B这俩个类
        pass
    print(C.__bases__)#C的父类
    print(C.__dict__)#C中的方法
    print(C.__name__)#C的名字
    #输出:
    (<class '__main__.A'>, <class '__main__.B'>)
    {'__module__': '__main__', '__doc__': None}
    C
    
    
    

    二、利用继承减少代码冗余

    2.1 减少冗余

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

    class Person(object):
        school = 'oldboy'
        def __init__(self,name,age):
            self.name = name
            self.age = age
    class Teacher(Person):
        pass
    class Student(Person):
        pass
    stu = Student('crean',18)
    print(stu.name)
    

    2.2多层继承

    class A:
        h = "AAA"
    class B(A):
        h = "BBB"
    class C(B):
        h = "CCC"
    class D(C):
        # h = "DDD"
        pass
    d = D()
    print(d.h)
    #
    CCC
    
    class A:
        h = "AAA"
    class B:
        h = "BBB"
    class C:
        h = "CCC"
    class D(A,B,C):
        # h = "DDD"
        pass
    d = D()
    print(d.h)
    #
    AAA
    

    三、继承的菱形问题

    3.1菱形问题

    class G(object):
        a = "GGG"
        pass
    class F(G):
        # a = "FFF"
        pass
    class E(G):
        # a = "EEE"
        pass
    class D(G):
        # a = "DDD"
        pass
    class C(F):
        # a="CCC"
        pass
    class B(E):
        # a="BBB"
        pass
    class A(B,C,D):
        # a="AAAA"
        pass
    a = A()
    print(a.a)
    print(A.mro())
    print(A.__mro__)
    
    #
    GGG
    [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>]
    (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
    
    
    

    mro()列表,继承顺序查找列表(只在新式类中有)1

    mro()和、__mro__是相等的

    print(A.mro())
    print(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'>]
    (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.F'>, <class '__main__.D'>, <class '__main__.G'>, <class 'object'>)
    

    3.2对菱形问题的总结

    1. 继承的菱形问题(显示的都继承一个类,不是object类):新式类和经典类的查找顺序是不一样的
    2. 新式类(py3中全是新式类):广度优先---从左侧开始,一直往上找,找到菱形的顶点结束(不包括菱形顶点),继续下一个继承的父类往上找,找到菱形的顶点结束(不包括菱形顶点),最后找到菱形顶点
    3. 经典类(只有py2中才有):深度优先---从左侧开始,一直往上找,找到菱形的顶点结束(包括菱形顶点)继续下一个继承的父类往上找,找到菱形的顶点结束(不包含菱形定点)(经典类就是没有继承(object))
    4. 不出现菱形问题:正常查找

    四、如何重用父亲的属性和方法

    4.1 如何重用父亲的属性和方法一

    继承重用父亲类方法1:指明道姓的使用,跟继承没有关系

    class Person:
        school = 'oldboy'
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def study(self):
            print("study....")
    class Student(Person):
        def __init__(self,name,age,course):
            #重用父类的__init__方法
            Person.__init__(self,name,age)
            self.course = course
        def study(self):
            #重用父类的__init__方法
            Person.study(self)
            print("%s学生在学习"%self.name)
    stu1 = Student('chen','18','python')
    print(stu1.school)
    stu1.study()
    #
    
    oldboy
    study....
    chen学生在学习
    

    4.2如何重用父类的属性和方法二

    继承重用父类方法二:通过super关键字,跟继承是有关系

    class Person(object):
        school = 'oldboy'
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def study(self):
            print('study...')
    class Student(Person):
        def __init__(self,name,age,course):
            #super()会按照mro列表拿出父亲对象
            #对象来调用绑定方法,不需要传递第一个参数(self)
            super().__init__(name,age)
            #在新式类中一般都是上面的写法
            #在经典类(python2)中必须严格用另外一种方式写,如下:
            #super(Student,self).__init__(name,age)这种方式也可以在python3种使用
            self.course = course
        def study(self):
            super().study()
    
    
    stu = Student('ocera',18,'python')
    print(stu.school)
    stu.study()
    #
    oldboy
    study...
    
    

    总结

    • super()相当于得到了一个特殊对象,第一个参数不需要传,调用绑定方法,会把自己传过去。
    • 这么写:super(类名,对象) 在py3中为了兼容py2。
    • 如果继承了多个父类,super是按照mro列表找,现在想指名道姓的用某个父类的某个方法,就需要指名道姓的使用

    4.3属性的查找顺序

    先找对象---->到类中寻找------>父类中找(多继承)-------->都找不到进行报错

  • 相关阅读:
    视图&索引&序列
    PL/SQL语言基础
    C#实现递归矩阵连乘(动态规划的递归自顶向下,非递归自地向上)
    JS 第五课
    请问,小丽的鞋子到底是什么颜色的?
    用10!来回顾 PL/SQL语言基础 && 标准异常名
    SELECT 查询—子查询
    备份和恢复
    JS 第六课
    Linux学习之二Linux系统的目录结构
  • 原文地址:https://www.cnblogs.com/SkyOceanchen/p/11420100.html
Copyright © 2011-2022 走看看