Appearance
27|继承与多态
多个类有相同的属性和方法时,可以把公共部分提取到一个父类,子类继承父类后自动拥有这些公共部分。子类还可以添加自己的特性,或修改父类的行为。
一、继承
python
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现这个方法")
class Dog(Animal):
def speak(self):
return f"{self.name} says woof"
class Cat(Animal):
def speak(self):
return f"{self.name} says meow"
dog = Dog("Buddy")
cat = Cat("Kitty")
print(dog.speak()) # Buddy says woof
print(cat.speak()) # Kitty says meowDog(Animal) 表示 Dog 继承自 Animal。Dog 自动拥有 Animal 的 __init__ 方法,但重写了 speak 方法。
二、调用父类方法
子类需要在父类的基础上扩展时,用 super() 调用父类方法:
python
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
class GraduateStudent(Student):
def __init__(self, name, age, major):
super().__init__(name, age) # 调用父类的 __init__
self.major = major
grad = GraduateStudent("Alice", 24, "CS")
print(grad.name) # Alice
print(grad.major) # CSsuper() 返回父类的代理对象,通过它调用父类的方法。在多重继承时,super() 按 MRO(方法解析顺序)查找下一个类,不一定是直接父类。
三、方法重写
子类重写父类的方法:
python
class Rectangle:
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 Square(Rectangle):
def __init__(self, side):
super().__init__(side, side)
def describe(self):
return f"正方形,面积={self.area()}"
sq = Square(5)
print(sq.describe()) # 正方形,面积=25Square 继承 Rectangle,重写了 __init__(强制宽和高相等)和 describe(修改描述文本)。
四、多态
不同的子类对象可以响应同一个方法调用,各自执行自己的实现:
python
animals = [Dog("Buddy"), Cat("Kitty")]
for animal in animals:
print(animal.speak())
# Buddy says woof
# Kitty says meowanimal.speak() 的具体行为取决于 animal 实际是什么类的对象。Python 是动态类型语言,多态不需要显式声明接口——只要对象有 speak 方法,就能调用。
五、类型检查
判断对象是否是某个类的实例:
python
dog = Dog("Buddy")
isinstance(dog, Dog) # True
isinstance(dog, Animal) # True,Dog 是 Animal 的子类
isinstance(dog, Cat) # False判断类之间的继承关系:
python
issubclass(Dog, Animal) # True
issubclass(Cat, Dog) # False六、抽象基类
如果父类的方法不应该被直接调用(如 Animal.speak),可以把父类定义为抽象基类:
python
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
# 不能直接实例化抽象类
animal = Animal() # TypeError: Can't instantiate abstract class子类必须实现所有抽象方法才能实例化:
python
class Dog(Animal):
def speak(self):
return "woof"
dog = Dog() # 可以,实现了 speak抽象基类强制子类实现特定方法,适合定义接口规范的场景。
七、多重继承
Python 支持一个类继承多个父类:
python
class Flyable:
def fly(self):
return "flying"
class Swimmable:
def swim(self):
return "swimming"
class Duck(Animal, Flyable, Swimmable):
def speak(self):
return "quack"
duck = Duck("Donald")
print(duck.speak()) # quack
print(duck.fly()) # flying
print(duck.swim()) # swimming多重继承的复杂性在于方法解析顺序(MRO)。如果多个父类有同名方法,Python 按 MRO 顺序查找。可以通过 ClassName.__mro__ 查看解析顺序。
多重继承能简化代码,但也增加了理解成本。类层次简单时,组合(把一个类的实例作为另一个类的属性)通常比多重继承更清晰。
记忆锚点:class Child(Parent) 继承;super() 调用父类方法;子类重写父类方法实现多态;isinstance() 判断对象类型,issubclass() 判断继承关系;@abstractmethod 定义抽象方法,强制子类实现;多重继承按 MRO 顺序解析;优先用组合替代复杂的多重继承。