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() 的调用顺序直观地画出来)

相关推荐
Q_Q5110082859 小时前
python+django/flask的图书馆管理系统vue
spring boot·python·django·flask·node.js·php
cwh_rs_giser9 小时前
如何高效设置机器学习超参数?——借鉴成熟AutoML框架的实践
人工智能·python·机器学习
逻极9 小时前
Scikit-learn 入门指南:从零到一掌握机器学习经典库(2025 最新版)
人工智能·python·机器学习·ai·scikit-learn·agent
麦麦鸡腿堡9 小时前
Java_HashMap底层机制与原码解读
java·开发语言·jvm
草莓熊Lotso9 小时前
C++ 抽象类与多态原理深度解析:从纯虚函数到虚表机制(附高频面试题)
java·运维·服务器·开发语言·c++·人工智能·笔记
Rock_yzh9 小时前
LeetCode算法刷题——49. 字母异位词分组
数据结构·c++·学习·算法·leetcode·职场和发展·哈希算法
Wayfreem9 小时前
Spring AI Alibaba 学习之最简单的快速入门
人工智能·学习·spring
再玩一会儿看代码9 小时前
Ken的Java学习之路——Java中关于面向对象
java·开发语言·经验分享·python·学习
迦蓝叶9 小时前
通过 HelloWorld 深入剖析 JVM 启动过程
java·开发语言·jvm·aot·启动过程·helloword·leyden
Q_Q51100828510 小时前
python+django/flask的美食交流宣传系统vue
spring boot·python·pycharm·django·flask·node.js·php