Python 继承机制
继承允许子类获取父类的属性和方法,实现代码复用与扩展。
单继承
Python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return "动物叫声"
class Dog(Animal): # 继承 Animal
def speak(self): # 方法重写
return "汪汪"
class Cat(Animal):
def speak(self):
return "喵喵"
dog = Dog("小狗")
cat = Cat("小猫")
print(dog.name) # 小狗(继承父类属性)
print(dog.speak()) # 汪汪(重写的方法)
print(cat.speak()) # 喵喵
super() 调用父类方法
Python
class Parent:
def __init__(self, name):
self.name = name
print("Parent 初始化")
def method(self):
print("Parent 方法")
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # 调用父类 __init__
self.age = age
print("Child 初始化")
def method(self):
super().method() # 调用父类方法
print("Child 方法")
c = Child("Alice", 25)
# Parent 初始化
# Child 初始化
c.method()
# Parent 方法
# Child 方法
方法重写(Override)
Python
class Shape:
def area(self):
return 0
def describe(self):
return "这是一个形状"
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self): # 重写
return self.width * self.height
def describe(self): # 重写并扩展
return f"这是一个矩形,面积: {self.area()}"
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
r = Rectangle(5, 3)
print(r.area()) # 15
print(r.describe()) # 这是一个矩形,面积: 15
多继承
Python
class A:
def method(self):
print("A 方法")
class B:
def method(self):
print("B 方法")
class C(A, B): # 多继承
pass
c = C()
c.method() # A 方法(继承顺序决定)
MRO(方法解析顺序)
Python
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
d = D()
d.method() # B(MRO: D → B → C → A)
print(D.__mro__)
# (<class 'D'>, <class 'B'>, <class 'C'>, <class 'A'>, <class 'object'>)
print(D.mro()) # 返回列表形式
# [D, B, C, A, object]
C3 算法
MRO 使用 C3 算法计算,规则:
- 子类优先于父类
- 多个父类按继承顺序
- 同一父类只出现一次
Python
class X:
pass
class Y:
pass
class Z:
pass
class A(X, Y):
pass
class B(Y, Z):
pass
class C(A, B):
pass
print(C.mro())
# [C, A, X, B, Y, Z, object]
多继承中的 super()
Python
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
print("B")
super().__init__() # 调用 MRO 中的下一个
class C(A):
def __init__(self):
print("C")
super().__init__() # 调用 MRO 中的下一个
class D(B, C):
def __init__(self):
print("D")
super().__init__() # 按 MRO 链式调用
d = D()
# D → B → C → A
# D.mro() = [D, B, C, A, object]
继承中的属性查找
Python
class Base:
base_attr = "基类属性"
class Middle(Base):
middle_attr = "中间类属性"
class Derived(Middle):
derived_attr = "派生类属性"
d = Derived()
print(d.derived_attr) # 派生类属性
print(d.middle_attr) # 中间类属性
print(d.base_attr) # 基类属性
# 查找顺序:实例 → Derived → Middle → Base → object
isinstance 与 issubclass
Python
class Animal:
pass
class Dog(Animal):
pass
d = Dog()
print(isinstance(d, Dog)) # True
print(isinstance(d, Animal)) # True
print(isinstance(d, object)) # True
print(issubclass(Dog, Animal)) # True
print(issubclass(Animal, Dog)) # False
print(issubclass(Dog, object)) # True
检查继承关系
Python
class Base:
pass
class Derived(Base):
pass
print(Derived.__bases__) # (<class 'Base'>,) 直接父类
print(Derived.__base__) # <class 'Base'> 第一个父类
print(Base.__subclasses__()) # [<class 'Derived'>] 子类列表
Mixin 模式
Mixin 是提供额外功能的小类,不独立使用:
Python
class LogMixin:
"日志 Mixin"
def log(self, message):
print(f"[LOG] {message}")
class SerializeMixin:
"序列化 Mixin"
def to_dict(self):
return self.__dict__.copy()
class User(LogMixin, SerializeMixin):
def __init__(self, name, age):
self.name = name
self.age = age
u = User("Alice", 25)
u.log("用户创建") # [LOG] 用户创建
print(u.to_dict()) # {'name': 'Alice', 'age': 25}
Mixin 类通常不定义
__init__,只提供方法扩展。
抽象继承
结合 abc 模块强制子类实现方法:
Python
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def connect(self):
pass
class MySQL(Database):
def connect(self):
print("连接 MySQL")
class PostgreSQL(Database):
def connect(self):
print("连接 PostgreSQL")
继承 vs 组合
| 方式 | 特点 |
|---|---|
| 继承 | 紧耦合,复用父类实现 |
| 组合 | 松耦合,灵活组装功能 |
Python
# 继承方式
class Animal:
def move(self):
print("移动")
class Dog(Animal):
pass # 继承 move
# 组合方式
class Movement:
def move(self):
print("移动")
class Dog2:
def __init__(self):
self.movement = Movement() # 组合
def move(self):
self.movement.move()
钻石继承问题
Python
class A:
def __init__(self):
print("A")
class B(A):
def __init__(self):
A.__init__(self) # 直接调用(不推荐)
print("B")
class C(A):
def __init__(self):
A.__init__(self) # 直接调用(不推荐)
print("C")
class D(B, C):
def __init__(self):
B.__init__(self)
C.__init__(self)
print("D")
d = D()
# A 被调用两次
# A → B → A → C → D
# 使用 super() 解决
class B(A):
def __init__(self):
super().__init__() # 按 MRO 调用
print("B")
要点总结
| 要点 | 说明 |
|---|---|
| 单继承 | 子类继承一个父类 |
| 多继承 | 子类继承多个父类,按 MRO 查找 |
super() | 调用 MRO 中的下一个类方法 |
| MRO | C3 算法,类.mro() 查看 |
| 方法重写 | 子类重新定义父类方法 |
多继承推荐使用 Mixin 模式,避免复杂的继承层次;使用
super()保证方法正确调用。
D:\git2\jwdev\articles\PYTHON\进阶\面向对象编程\继承机制.md
📝 发现内容有误?点击此处直接编辑