python深入之类继承资源的覆盖和累加

关于类继承资源的覆盖

(1)体现:覆盖和重写

(2)原理:根据MRO链的优先级,对类中的资源进行调用时,会优先调用优先级高的类中的资源,这样,如果优先级低的类中也有同样的资源,则不会被调用,这就相当于是被覆盖了;重写也是同样的道理,重写后的资源会被优先调用,覆盖掉优先级低的类中的相同资源

(3)注意调用资源时self和cls的变化:使用的是谁实例化出来的对象,或使用的是哪那个类,self就是哪个实例,cls就是哪个类

关于类继承资源的累加

(1)概念:在一个父类的基础上,增加一个子类自己特有的资源

(2)场景:1.子类与父类相比,多一些属于自己的资源;2.在被覆盖的方法基础之上,新增功能

(3)场景1代码实现:

class A(object):
    a = 10
    def __init__(self):
        self.aa = 1
    def a3(self):
        print("a3")
    @classmethod
    def a1(cls):
        print("a1")
    @staticmethod
    def a2():
        print("a2")
class B(A):
    b = 9
    def b3(self):
        print("b3")
    @classmethod
    def b1(cls):
        print("b1")
    @staticmethod
    def b2():
        print("b2")

(4)场景2有两种实现方法,第一种是在B类中重写A中方法,并在加入新功能后对A中的方法进行调用,代码如下:

class A(object):
    a = 10
    def aa(self):
        print("aa")
class B(A):
    def bb(self):
        print("bb")
        A.aa(self)
b = B()
b.bb()

这里aa()是A类的实例方法,但是在B类中对其进行调用时,不能使用A类的实例对象进行调用,因为这里是给B的实例方法新增内容,如果使用A类的实例对象进行调用,则不会将内容增加到B的实例方法中,代码A.aa(self)中的self是bb()方法传进来 ,所以是B的实例对象;这里使用的方式其实也存在弊端,那就是如果父类的类名被改变,那么在子类中调用父类方法时,前面的父类类名就要跟着改变,这样的代码就很不好了

方式二:在低优先级的类中通过super来调用高优先级的类方法(重点)。

super概念:super是一个类,且只有在新式类中才有效

super作用:代理作用,它沿着MRO链寻找下一级节点,并调用对应的方法。这里需要注意的是,在MRO链中属于上下级关系的不一定是继承关系,例如有重叠多继承形态的MRO链

super中需要解决的问题:1.找谁的下一个节点;2沿着谁的MRO链条.;3.参数如何传递

super的语法原理:

super的常用语法形式:

使用super对方法进行新增内容,代码如下:

class A(object):
    a = 10
    def aa(self):
        print("aa")
        self.a1 = 19
class B(A):
    def bb(self):
        print("bb")
        self.b1 = 20
        super(B, self).aa()
b = B()
b.bb()

填super中的两个参数时要考虑两个问题,首先,是在找谁的下一个节点,这里是找A,而A是B的下一个节点,所以第一个参数填B类;然后是沿着谁的MRO链条寻找,有前面语法原理知,是要找一条MRO链条,并找到B类在该链条中的索引位置,然后加1,就可以找到下一个节点的索引位置,那么,要找的这条MRO链条一定要包含有B类,所以,第二个参数可以填B类和其实例或者B类的子类和其实例。第二个参数的作用除了寻找MRO链条,还决定了向A类方法中传第的参数,所以这里如果需要传递类,则第二个参数填类,需要传递实例,则第二个参数填实例。上述代码中aa(self)方法是实例方法,需要传递实例,所以super的第二个参数直接填self即可,这里的self表示B类的实例

猜你喜欢

转载自blog.csdn.net/zx870121209/article/details/81414108