一、继承的基本概念
继承是面向对象编程的三大特性之一(封装、继承、多态),它允许我们定义一个类(子类)来继承另一个类(父类)的属性和方法。
1. 基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class ParentClass: """父类/基类""" def parent_method(self): print("这是父类方法")
class ChildClass(ParentClass): """子类/派生类""" def child_method(self): print("这是子类方法")
child = ChildClass() child.parent_method() child.child_method()
|
2. 继承的特性
- 子类继承父类的所有公有属性和方法
- 子类可以扩展父类的功能
- 子类可以重写父类的方法
- 子类的实例也是父类的实例(
isinstance
返回 True
)
二、方法重写(Override)
子类可以重新定义父类的方法,这称为方法重写。
1. 完全重写
1 2 3 4 5 6 7 8 9 10 11
| class Animal: def speak(self): print("动物发出声音")
class Dog(Animal): def speak(self): print("汪汪汪!")
dog = Dog() dog.speak()
|
2. 扩展父类方法(使用 super())
1 2 3 4 5 6 7 8 9 10 11 12
| class Animal: def __init__(self, name): self.name = name
class Cat(Animal): def __init__(self, name, color): super().__init__(name) self.color = color
cat = Cat("咪咪", "白色") print(f"名字: {cat.name}, 颜色: {cat.color}")
|
三、多重继承
Python 支持多重继承,即一个类可以继承多个父类。
1. 基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Father: def father_method(self): print("父亲的方法")
class Mother: def mother_method(self): print("母亲的方法")
class Child(Father, Mother): def child_method(self): print("孩子的方法")
child = Child() child.father_method() child.mother_method() child.child_method()
|
2. 方法解析顺序(MRO)
当多个父类有同名方法时,Python 使用 C3 算法确定调用顺序,可以通过 类名.__mro__
查看。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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
print(D.__mro__)
d = D() d.method()
|
3. 菱形继承问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class A: def method(self): print("A的方法")
class B(A): def method(self): print("B的方法") super().method()
class C(A): def method(self): print("C的方法") super().method()
class D(B, C): def method(self): print("D的方法") super().method()
d = D() d.method() """ 输出: D的方法 B的方法 C的方法 A的方法 """
|
四、特殊方法与继承
1. __init__
方法的继承
1 2 3 4 5 6 7 8 9 10 11 12
| class Person: def __init__(self, name): self.name = name
class Student(Person): def __init__(self, name, student_id): super().__init__(name) self.student_id = student_id
student = Student("张三", "2023001") print(student.name, student.student_id)
|
2. 其他特殊方法的重写
1 2 3 4 5 6 7
| class MyList(list): def __str__(self): return f"MyList: {super().__str__()}"
lst = MyList([1, 2, 3]) print(lst)
|
五、抽象基类与接口
Python 通过 abc
模块支持抽象基类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| from abc import ABC, abstractmethod
class Shape(ABC): @abstractmethod def area(self): pass
@abstractmethod def perimeter(self): pass
class Circle(Shape): def __init__(self, radius): self.radius = radius
def area(self): return 3.14 * self.radius ** 2
def perimeter(self): return 2 * 3.14 * self.radius
circle = Circle(5) print(circle.area())
|
六、继承的最佳实践
- 优先使用组合而非继承:除非确实是”is-a”关系
- 避免深度继承:继承层次不宜过深
- 合理使用多重继承:谨慎设计,避免复杂关系
- 使用抽象基类定义接口:明确子类需要实现的方法
- 遵循LSP原则:子类应该能够替换父类
七、完整示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Animal: def __init__(self, name): self.name = name def eat(self): print(f"{self.name}正在吃东西")
class Flyable: def fly(self): print(f"{self.name}正在飞翔")
class Swimable: def swim(self): print(f"{self.name}正在游泳")
class Bird(Animal, Flyable): def __init__(self, name): super().__init__(name) def speak(self): print(f"{self.name}在唱歌")
class Duck(Bird, Swimable): def __init__(self, name): super().__init__(name) def speak(self): print(f"{self.name}在嘎嘎叫")
duck = Duck("唐老鸭") duck.eat() duck.fly() duck.swim() duck.speak()
|