目录
继承的概念
继承是面向对象编程的三大特性之一,它允许我们定义一个类(子类/派生类)来继承另一个类(父类/基类)的属性和方法。继承的主要目的是实现代码重用和层次化类设计。
单继承基础
最简单的继承形式是子类继承自单个父类:
# 父类(基类)
class Human:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} 在说话...")
def walk(self):
print(f"{self.name} 在散步...")
# 子类(派生类)
class Student(Human):
pass # 直接继承父类的所有属性和方法
class Teacher(Human):
pass # 直接继承父类的所有属性和方法
# 使用示例
p1 = Human("小米同志")
p1.speak() # 小米同志 在说话...
s1 = Student("小草")
s1.speak() # 小草 在说话...
t1 = Teacher("老师")
t1.speak() # 老师 在说话...
方法的覆盖与扩展
子类可以覆盖父类的方法,也可以扩展父类的方法:
class Human:
def __init__(self, name):
self.name = name
def speak(self):
print(f"{self.name} 在说话...")
class Student(Human):
def __init__(self, name, edu, age):
# 调用父类的初始化方法
super().__init__(name)
# 子类特有的属性
self.edu = edu
self.age = age
# 覆盖并扩展父类方法
def speak(self):
super().speak() # 先调用父类的方法
self.age += 1 # 子类特有的逻辑
print(f"{self.name} 在说话...我是{self.edu}...今年{self.age}岁了")
# 使用方法解析顺序(MRO)查看继承关系
s1 = Student("小米", "本科", 18)
print("方法解析顺序:", Student.__mro__)
s1.speak()
输出结果:
方法解析顺序: (<class '__main__.Student'>, <class '__main__.Human'>, <class 'object'>)
小米 在说话...
小米 在说话...我是本科...今年19岁了
多继承
Python支持多继承,即一个类可以继承自多个父类:
class A:
def speak(self):
print("A.method")
class B(A):
pass
class C(A):
pass
class D(A):
pass
class E(B, C, D): # 多继承,从左到右查找方法
pass
# 查看方法解析顺序(MRO)
print(E.__mro__)
e = E()
e.speak() # 输出: A.method
super()函数详解
super()
函数用于调用父类(超类)的方法,在继承关系中非常有用:
-
在单继承中,
super()
简单地引用父类 -
在多继承中,
super()
遵循MRO顺序调用方法
class Parent:
def __init__(self, name):
self.name = name
print("Parent __init__ called")
class Child(Parent):
def __init__(self, name, age):
super().__init__(name) # 调用父类的__init__
self.age = age
print("Child __init__ called")
c = Child("小明", 10)
方法解析顺序(MRO)
MRO(Method Resolution Order)决定了Python在多继承中查找方法的顺序:
-
Python 2.3之前使用深度优先搜索(DFS)
-
Python 2.3开始使用C3线性化算法
-
可以通过
类名.__mro__
或类名.mro()
查看
class X: pass
class Y: pass
class Z: pass
class A(X, Y): pass
class B(Y, Z): pass
class M(A, B, Z): pass
print(M.mro())
输出结果:
[<class '__main__.M'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class 'object'>]
继承的最佳实践
-
优先使用组合而非继承:除非确实是"is-a"关系
-
避免多重继承的复杂性:除非确实需要
-
使用抽象基类(ABC):定义接口规范
-
合理使用super():确保初始化顺序正确
-
遵循LSP原则:里氏替换原则,子类应该能够替换父类
总结
-
继承实现了代码的重用和层次化设计
-
子类可以覆盖或扩展父类的方法
-
Python支持多继承,通过MRO确定方法查找顺序
-
super()
函数是调用父类方法的标准方式 -
理解MRO对于处理复杂继承关系至关重要
合理使用继承可以创建出结构良好、易于维护的代码结构,但过度使用继承特别是多重继承可能导致代码难以理解和维护。