Python学习(10) ----- Python的继承


🧩 一、什么是继承(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 继承 Parent
  • Child 拥有 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() 的调用顺序直观地画出来)

相关推荐
中等生4 小时前
uv 完全指南:Python 包管理的现代化解决方案
python
newxtc4 小时前
【广州公共资源交易-注册安全分析报告-无验证方式导致安全隐患】
开发语言·selenium·安全·yolo
懒羊羊不懒@4 小时前
Java一、二维数组
开发语言·python
中等生4 小时前
uvicorn 和 gunicorn
python
爱学习的小鱼gogo4 小时前
python 单词搜索(回溯-矩阵-字符串-中等)含源码(二十)
开发语言·数据结构·python·矩阵·字符串·回溯·递归栈
徐同保4 小时前
Redux和@reduxjs/toolkit同时在Next.js项目中使用
开发语言·前端·javascript
CandyU24 小时前
C++ 学习 —— 02 - 排序算法
c++·学习·排序算法
~无忧花开~4 小时前
CSS学习笔记(二):CSS动画核心属性全解析
开发语言·前端·css·笔记·学习·css3·动画
AI 嗯啦4 小时前
深度学习——Python 爬虫原理与实战:从入门到项目实践
爬虫·python·深度学习