多继承允许类同时继承多个父类,实现功能组合,但需解决菱形继承带来的方法解析问题。
Python 多继承语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class Parent1:
def method1(self):
print("Parent1 method1")
class Parent2:
def method2(self):
print("Parent2 method2")
class Child(Parent1, Parent2):
pass
child = Child()
child.method1() # Parent1 method1
child.method2() # Parent2 method2
|
菱形继承与 MRO
多继承核心挑战是方法解析顺序(MRO):多个父类存在同名方法时,如何确定调用哪个。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class A:
def method(self): print("A")
class B(A):
def method(self): print("B")
class C(A):
def method(self): print("C")
class D(B, C): # 菱形继承
pass
print(D.__mro__)
# (D, B, C, A, object) → 调用 B.method
|
C3 线性化算法原则
- 子类优先于父类
- 父类顺序保持定义时的顺序(
D(B, C) 中 B 优先于 C) - 避免循环依赖
super() 在多继承中的行为
super() 按 MRO 列表调用下一个类的方法,而非直接调用父类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| class A:
def method(self): print("A")
class B(A):
def method(self):
super().method() # 调用 C.method
print("B")
class C(A):
def method(self):
super().method() # 调用 A.method
print("C")
class D(B, C):
def method(self):
super().method()
print("D")
D().method() # 输出: A → C → B → D
|
应用场景
| 场景 | 说明 |
|---|
| Mixin 模式 | 为类添加独立功能模块 |
| 接口实现 | 同时实现多个抽象接口 |
| 代码复用 | 复用多个不相关类的功能 |
使用注意
- 避免复杂继承链,MRO 难以理解
- 多继承类保持单一职责
- 慎用同名方法,易触发意外行为
- 优先考虑组合而非继承
多语言对比
| 语言 | 类多继承 | 替代机制 |
|---|
| C++ | ✅ 支持 | 虚继承解决菱形问题 |
| Python | ✅ 支持 | C3 算法解决 MRO |
| Java | ❌ 禁止 | 接口多实现 |
| C# | ❌ 禁止 | 接口多实现 |
| Ruby | ❌ 禁止 | Module Mixin |
| PHP | ❌ 禁止 | Trait |
| Perl | ✅ 支持 | 深度优先查找 |
语言设计哲学的差异:C++ 追求灵活性,Java/C# 注重简洁性与可维护性,Ruby/PHP 用灵活机制模拟多继承。
Comments