python之路---继承与派生

什么是继承

  继承是一种新建类的方式,新建的类称之为:子类/派生类,被继承的类称之为:父类/基类/超类

继承的特性

1.python支持多继承(一个子类可以同时继承多个父类)

2.子类继承父类,可以重用父类的属性 --->减少了类与类之间的代码冗余

3.从继承的角度来看,python分为新式类和经典类

   新式类:继承object类的类以及他的子类(在python3中都默认继承object类,也就是说python3中只有新式类)

   经典类:没有继承object的类,在python2中新式类需要显式的继承,否则为经典类

   新式类和经典类的区别?

   1.从继承特性的角度看,继承object类的新式类可以重用object父类的属性,而经典类则不行

   2.从属性查找的角度看,新式类与经典类在菱形继承问题上属性的查找顺序有所区别

继承之属性查找

对于单继承:对象自己---->产生对象的类----产生对象的类的父类--->父类的父类(新式类包括object类).....,没有报错....

对于非菱形的多继承(一个子类同时继承了多个父类,这些父类最终没有继承同一个非object类的类):

  对象自己--->产生对象的类--->按照继承关系,从左到右,一条分支一条分支的查找,没有就报错,这里新式类与经典类无差

对于菱形继承问题(一个子类同时继承了多个父类,而这些父类最终又共同继承了同一个非object类的类):

    新式类:广度优先---->按照继承关系从左至右,一条分支一条分支的查找,But,只有在最后一条分支才会去找那个被多个父类共同继承的最终类(非object类)

    经典类:深度优先------->按照继承关系从左至右,一条分支一条分支的查找,But,在第一条分支就会去查找那个被多个父类共同继承的最终类

class Foo:
    def f1(self):
        print('foo.f1')
    def f2(self):
        print('foo.f2')
        self.f1()
class Bar(Foo):
    def f1(self):
        print('bar.f1')
f = Bar()
f.f2()

#foo.f2
#bar.f1

继承原理:

对于你定义的每一个类来说,python通过C3算法得出一个方法解析顺序MRO列表,这个列表就是简单的所有基类的线性顺序列表,python为了实现继承,会根据这这MRO列表从左至右查找基类,直到查到拥有这个属性的基类为止

这个MRO列表遵循下面三条准则:

1.子类会先于父类被检查

2.多个父类会根据它们在列表中的顺序被检查

3.如果对下一个类存在两个合法的选择,选择第一个父类

此外,python为我们内置了一个查看MRO列表的内置方法

class C(B, A):
    pass


print(C.mro())  #实际上就是print(C.__mro__)
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]


在子派生的新方法中重用父类方法的两种途径:

方法一:指名道姓的方式(本质就是函数的调用,无自动传值的效果,与继承无关)

class People:
    def __init__(self,name,age):
        self.name = name
        self.age  = age

class Student(People):
    def __init__(self,name,age,student_id):
        People.__init__(self,name,age)
        self.student_id = student_id
        

 方式二:使用super(自己的类名,对象名),它会得到一个特殊的对象,该对象专门用于访问父类的属性(该父类是指触发属性查找的类的父类),这是一种严格依赖于继承关系的方法,完全参照MRO列表

class B:
    def f1(self):
        print('B.f1')

    def f2(self):
        print('B.f2')
        super().f1()


class C(B, A):
    def f1(self):
        print('C.f1')


print(C.mro())
c = C()
c.f2()
#(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
#B.f2
#A.f1

猜你喜欢

转载自blog.csdn.net/ltfdsy/article/details/81870211