Skip to content

Python: 多态

多态指的是同一操作在不同对象上可以产生不同的行为。在 Python 中,多态是通过方法覆盖实现的,子类可以重写父类的方法,从而实现不同的行为。

多态的概念

  • 同一操作,不同行为: 同一个方法在不同的对象上可以执行不同的操作,产生不同的结果。
  • 动态绑定: 方法的调用在运行时才确定,根据对象的实际类型来决定调用哪个方法。

多态的实现

在 Python 中,多态是通过方法覆盖和动态绑定实现的:

  • 方法覆盖: 子类可以重写父类的方法,实现不同的行为。
  • 动态绑定: 方法的调用在运行时根据对象的实际类型来决定调用哪个方法。

多态示例

不同动物 speak() 方法产生不同的行为,这就是多态的表现。

python
class Animal:
    def __init__(self, name, species):
        self.name = name
        self.species = species

    def speak(self):
        print(f"{self.name} makes a sound.")

class Dog(Animal):
    def speak(self):
        print(f"{self.name} barks!")

class Cat(Animal):
    def speak(self):
        print(f"{self.name} meows!")

class Bird(Animal):
    def speak(self):
        print(f"{self.name} tweets!")

# 创建动物实例
dog = Dog("Buddy", "Golden Retriever")
cat = Cat("Whiskers", "Siamese")
bird = Bird("Tweety", "Canary")

# 使用多态调用 speak() 方法
animals = [dog, cat, bird]
for animal in animals:
    animal.speak()

多态的优点

  • 代码简洁: 使用多态可以减少重复代码,提高代码可读性和可维护性。
  • 代码可扩展性: 可以在不修改现有代码的情况下,添加新的子类,扩展功能。
  • 代码灵活性: 多态允许我们使用统一的接口来处理不同类型的对象,提高代码的灵活性和适应性。

多态与抽象类

  • 抽象类: 抽象类是不能被实例化的类,它通常用于定义一些通用的方法,但不提供具体实现。
  • 多态与抽象类: 抽象类可以用来实现多态。子类继承抽象类并实现抽象方法,就可以实现不同的行为。
python
from abc import ABC, abstractmethod

# 定义抽象基类 Shape
class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

# 定义矩形类 Rectangle,继承 Shape
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

# 定义圆形类 Circle,继承 Shape
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14159 * self.radius * self.radius

# 创建矩形和圆形实例
rect = Rectangle(5, 10)
circle = Circle(5)

# 计算面积
print(f"矩形面积: {rect.area()}")  # 输出:矩形面积: 50
print(f"圆形面积: {circle.area()}")  # 输出:圆形面积: 78.53975

# 尝试实例化 Shape 类
# shape = Shape()  # 报错:TypeError: Can't instantiate abstract class Shape with abstract methods area

ABC 代表 抽象基类 (Abstract Base Class)。它是一种特殊的类,不能被直接实例化,但可以作为其他类的父类。抽象基类的主要作用是定义接口,即方法的签名,但不提供具体实现。子类必须实现抽象基类中定义的抽象方法,才能被实例化。

  1. 我们使用 from abc import ABC, abstractmethod 导入 ABCabstractmethod 用于定义抽象基类和抽象方法。
  2. Shape 类是一个抽象基类,它定义了一个抽象方法 area(),但没有提供具体实现。
  3. RectangleCircle 类继承了 Shape 类,并分别实现了 area() 方法,计算矩形和圆形的面积。
  4. 由于 Shape 类是一个抽象基类,无法直接实例化,尝试实例化会导致错误。

总结

多态,无需确切的知晓它的子类,由运行时该对象的确切类型决定,这就是多态的魅力,只要保证新增的子类正确实现了抽象方法即可,即著名的开闭原则: 对扩展开放,对修改关闭。

Released under the MIT License.