对于Python中多重继承不太清楚,所以看了下相关文章。
以下摘自http://www.cnblogs.com/yiranlaobaitu/p/3764422.html
如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中保留改间接共同基类数据成员的多份同名成员。
在一个类中保留间接共同基类的多份同名成员,这种现象是人们不希望出现的。C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员。
C++在存在多个同名成员时,会报错,如
#include <iostream>
using namespace std;
class A{
public:
void method(){
cout<<"A"<<endl;
}
};
class B: public A{
};
class C{
public:
void method(){
cout<<"C"<<endl;
}
};
class D: public B, public C{
};
int main(){
D d;
d.method():
}
或者
#include <iostream>
using namespace std;
class A{
public:
void method(){
cout<<"A"<<endl;
}
};
class B: public A{
};
class C: public A{
};
class D: public B, public C{
};
int main(){
D d;
d.method():
}
编译就会报错
error: request for member 'method' is ambiguous
正确的写法应该是用virtual class
#include <iostream>
using namespace std;
class A{
public:
void method(){
cout<<"A"<<endl;
}
};
class B: virtual public A{
};
class C: virtual public A{
};
class D: public B, public C{
};
int main(){
D d;
d.method():
}
和C++不同,Python在多重继承时中可以存在多个同名成员
class A:
def __init__(self):
print 'A'
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
d = D()
python中采用MRO来处理这种二义性问题。
MRO的起源可以参考这篇文章:http://python.jobbole.com/85685/
这里只总结了下结论
Python2.2以前的版本:经典类时代,深度优先搜索
Python2.2版本:经典类MRO为深度优先搜索,新式类MRO为BFS
Python2.3到Python2.7:经典类和新式类采用C3算法
Python3:只有新式类,算法依然是C3算法
那么,什么是C3算法呢?
用C1C2…CN来记录类[C1, C2, …, CN]
另C是从B1, B2, …, BN继承,我们需要计算C的linearization L[C],
L[C(B1,…BN)] = C + merge(L[B1]L[B2]…L[BN], B1…BN)
且L[object] = object
看官网上的公式没明白那个merge是什么,后来从上面的链接看到,其实就是拓扑排序!
假设继承关系如下:
class D(object):
pass
class E(object):
pass
class F(object):
pass
class C(D, F):
pass
class B(E, D):
pass
class A(B, C):
pass
if __name__ == '__main__':
print A.__mro__
得到
在新式类中,可以用super()来调用继承过来的方法,但需要注意的是,super()并不是调用父类,而是调用的继承顺序的下一个类,super()的第一个参数也可以是继承链中的任意一个类。