[super][继承][面向对象][构造函数][多重继承]

来源:互联网 发布:windows命名规则 编辑:程序博客网 时间:2024/05/21 06:25

super()内置函数

父类的构造函数必须手动调用, 调用方式有2种:
1. MyParentClass.__init__(xxx)
2. super(MyClass, self).__init__(xxx)

区别在于: 1比较直观, 在涉及多重继承时, 可以手动控制父类构造函数的调用顺序, 需要手动为每个父类调用一次构造函数; 2比较灵活, 动态查找父类, 在涉及多重继承时, 会自动调用各个直接父类的构造函数;

class A(object):    def __init__(self):        super(A, self).__init__()        print '__init__ A'class B(A):    def __init__(self):        super(B, self).__init__()        print '__init__ B'class C(B):    def __init__(self):        super(C, self).__init__()        print '__init__ C'class AA(object):    def __init__(self):        super(AA, self).__init__()        print '__init__ AA'class D(A, AA):    def __init__(self):        super(D, self).__init__()        print '__init__ D'd = D()# 自动调用所以直接父类的构造函数#__init__ AA#__init__ A#__init__ Dclass BB(A):    def __init__(self):        print '__init__ BB'class CC(BB):    def __init__(self):        super(CC, self).__init__()        print '__init__ CC'cc = CC()# super()只会查找直接父类, 不会递归查找, 所以, 因为BB没有调动super, 所以A的构造函数就被调用#__init__ BB#__init__ CCc = C()# 当前类和父类都调用了super, 所以才能保证继承链上的所有构造函数都被调用#__init__ A#__init__ B#__init__ C

三角继承

# 直接报错class A:    passclass B(A):    passclass C(B, A):    passc = C()#TypeError: Error when calling the metaclass bases    #Cannot create a consistent method resolution#order (MRO) for bases B, A

报错原因

C继承A和B, 同时B也继承A, 对C来说, B和A是它的2个直接父类, 所以C在进行方法查找时, A和B具有相同的优先级, 但是这时候问题就来了:
1. 如果先从A再B, 那么B会覆盖A的方法(当然了, 这是我们所期望的, 因为B是A子类, 子类覆盖父类, 是理所当然的)
2. 如果先从B再A, 那么A会覆盖B的方法(出错了吧! 父类方法怎么可以覆盖子类方法呢!)

以上2种情况均可能出现, 这导致了方法解析顺序(MRO)不一致

解决方法

既然B继承A, 那么B已经包含了A的全部内容, 所以直接继承B就可以了, 没有必要继承A了:

class C(B):    pass

万事大吉!

菱形继承

class A(object):    def __init__(self):        super(A, self).__init__()        print '__init__ A'class B(A):    def __init__(self):        super(B, self).__init__()        print '__init__ B'class C(A):    def __init__(self):        super(C, self).__init__()        print '__init__ C'class D(B, C):    def __init__(self):        super(D, self).__init__()        print '__init__ D'
阅读全文
0 0
原创粉丝点击