🧩 一、什么是继承(Inheritance)
继承就是:
一个类(子类)可以复用另一个类(父类)的属性和方法。
这样你就能"扩展"或"改写"已有逻辑,而不用重复写相同的代码。
🧱 二、基本语法
python
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def speak(self):
print("I'm the child.")
使用:
python
c = Child()
c.greet() # 继承自 Parent
c.speak() # 自己的方法
📍输出:
Hello from Parent
I'm the child.
✅ 说明:
Child(Parent)
表示 Child 继承 ParentChild
拥有Parent
的所有方法与属性
🪶 三、方法重写(Override)
子类可以"重写"父类的方法,以自定义行为:
python
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self): # 重写
print("Hi from Child")
使用:
python
Child().greet()
输出:
Hi from Child
🧭 四、调用父类方法(super)
如果你在重写方法时,还想用到父类的逻辑,可以用 super()
调用:
python
class Parent:
def greet(self):
print("Hello from Parent")
class Child(Parent):
def greet(self):
super().greet() # 调用父类方法
print("Hi from Child")
输出:
Hello from Parent
Hi from Child
🧬 五、构造函数继承(__init__
)
子类默认会继承父类的构造函数,但也可以自己定义:
python
class Parent:
def __init__(self, name):
self.name = name
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # 调用父类构造
self.age = age
使用:
python
c = Child("Tom", 10)
print(c.name, c.age)
输出:
Tom 10
🔁 六、多重继承(Multiple Inheritance)
Python 支持从多个父类继承:
python
class A:
def a_method(self):
print("A")
class B:
def b_method(self):
print("B")
class C(A, B): # 同时继承 A 和 B
pass
c = C()
c.a_method()
c.b_method()
输出:
A
B
✅ 注意:
如果多个父类中有同名方法,Python 会根据 方法解析顺序 (MRO) 决定调用哪个。
🧩 七、继承层次结构图(示例)
┌────────────┐
│ BaseClass │
└──────┬─────┘
│
┌──────┴─────┐
│ Child1 │
│ Child2 │
└─────────────┘
🧠 八、结合泛型的继承(高级)
Python 的 typing
模块允许你用泛型来声明"继承的类型参数",像这样:
python
from typing import Generic, TypeVar
T = TypeVar("T")
class Base(Generic[T]):
def __init__(self, value: T):
self.value = value
class Sub(Base[int]): # 继承并指定类型参数
pass
x = Sub(10)
print(x.value) # 类型是 int
✅ 九、总结
特性 | 说明 | 关键语法 |
---|---|---|
单继承 | 子类继承一个父类 | class Child(Parent) |
多继承 | 子类继承多个父类 | class C(A, B) |
方法重写 | 子类覆盖父类方法 | 同名函数 |
调用父类方法 | 使用 super() |
super().method() |
泛型继承 | 为继承关系加类型参数 | class Sub(Base[T]) |
是否希望我帮你用一段完整的代码演示
"父类 + 子类 + super 调用 + 重写 + 多继承"
的组合例子?这样你会对继承的运行顺序(MRO)也一目了然。
附录 - MRO
MRO(Method Resolution Order)------方法解析顺序 ,
决定了:
当多个父类中存在同名方法或属性 时,Python 按什么顺序查找调用。
🧩 一、基本概念
当你写:
python
class C(A, B):
...
然后你调用:
python
c = C()
c.some_method()
Python 会去查找 some_method
,顺序是:
先查找 C → 然后 A → 然后 B → 然后 A 和 B 的父类 → 最后到 object
这个查找路径的顺序就是 MRO。
🧱 二、简单示例
python
class A:
def hello(self):
print("A says hello")
class B:
def hello(self):
print("B says hello")
class C(A, B): # C 同时继承 A 和 B
pass
c = C()
c.hello()
📤 输出:
A says hello
因为 Python 的查找顺序是:
C → A → B → object
找到
A.hello()
就停了。
🔍 三、查看 MRO 顺序
你可以用内置属性 .mro()
或 __mro__
查看顺序:
python
print(C.mro())
输出:
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]
或者更直观:
python
for cls in C.mro():
print(cls.__name__)
输出:
C
A
B
object
⚙️ 四、如果继承顺序改一下
python
class C(B, A): # 顺序反过来
pass
print(C.mro())
输出:
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
🔁 此时:
python
C().hello()
输出:
B says hello
💡 结论:
多继承时的父类顺序决定了方法查找的优先级。
🧩 五、复杂继承结构(菱形继承)
所谓"菱形继承"(diamond inheritance):
A
/ \
B C
\ /
D
代码:
python
class A:
def hello(self):
print("A")
class B(A):
def hello(self):
print("B")
class C(A):
def hello(self):
print("C")
class D(B, C):
pass
print(D.mro())
D().hello()
输出:
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
B
💬 解释:
- Python 使用 C3 线性化算法 来生成 MRO;
- 它保证继承链 从左到右;
- 同时确保每个类只出现一次(防止重复调用)。
🧠 六、super() 与 MRO 的关系
当你用 super()
时,它不会直接调用父类 ,
而是会根据 MRO 顺序 找到下一个类。
示例:
python
class A:
def hello(self):
print("A")
class B(A):
def hello(self):
print("B")
super().hello()
class C(A):
def hello(self):
print("C")
super().hello()
class D(B, C):
def hello(self):
print("D")
super().hello()
D().hello()
输出:
D
B
C
A
💡 注意:
虽然 D 继承的是 (B, C)
,但 super()
是沿着 MRO 顺序依次调用的。
你可以看出:
super()
是"按 MRO 链条往下传递"的,不是简单的"调用父类"。
✅ 七、总结
概念 | 说明 |
---|---|
MRO | Method Resolution Order,方法解析顺序 |
作用 | 决定 Python 多继承时的查找顺序 |
查看方式 | ClassName.mro() 或 ClassName.__mro__ |
算法 | C3 线性化算法 |
super() 行为 | 按 MRO 顺序调用下一个类的方法 |
关键规律 | 从左到右、每个类只出现一次 |
是否希望我帮你画一张图,展示上面那个 "D(B, C)" 多重继承时的 MRO 调用路径图 ?
(会把 super()
的调用顺序直观地画出来)