继承&&新式类&&经典类

一、新式类和经典类

经典类: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属性的查找顺序

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

posted @ 2019-08-27 18:38  豆瓣酱瓣豆  阅读(278)  评论(0编辑  收藏  举报