张芷铭的个人博客

多继承允许类同时继承多个父类,实现功能组合,但需解决菱形继承带来的方法解析问题。

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 线性化算法原则

  1. 子类优先于父类
  2. 父类顺序保持定义时的顺序(D(B, C) 中 B 优先于 C)
  3. 避免循环依赖

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