当前位置:首页>python>Python多态——同一个接口,不同的实现

Python多态——同一个接口,不同的实现

  • 2026-10-10 20:46:20
Python多态——同一个接口,不同的实现

一、什么是多态?

多态(Polymorphism) 是面向对象编程的三大特性之一(封装、继承、多态)。它指的是同一个方法或操作,作用于不同的对象时,可以产生不同的行为结果。

简单来说:多态允许你用一个统一的接口(如方法名)来调用不同类型的对象,而每个对象会根据自身的类型给出相应的实现。

classDog:
defsound(self):
print("汪汪汪")

classCat:
defsound(self):
print("喵喵喵")

defmake_sound(animal):
    animal.sound()   # 统一的调用接口

make_sound(Dog())   # 汪汪汪
make_sound(Cat())   # 喵喵喵

二、为什么需要多态?

  • • 代码复用:编写通用的函数或类,可以处理多种不同类型的对象。
  • • 松耦合:调用方不需要知道对象的具体类型,只需要知道对象支持某个方法即可。
  • • 可扩展性:增加新类型时,无需修改已有的通用代码,只要新类型实现了约定好的接口。
  • 请在微信客户端打开


三、Python 中的多态实现方式

Python 的多态是**“鸭子类型(Duck Typing)”** 风格的:只要一个对象“看起来像鸭子,叫起来像鸭子”,那它就是鸭子。Python 不关心对象的类型,只关心对象是否具有所需的方法或属性。

3.1 继承多态

通过继承和方法重写实现多态是最传统的方式。

classAnimal:
defsound(self):
raise NotImplementedError("子类必须实现 sound 方法")

classDog(Animal):
defsound(self):
print("汪汪汪")

classCat(Animal):
defsound(self):
print("喵喵喵")

defanimal_sound(animal):
    animal.sound()

animals = [Dog(), Cat()]
for a in animals:
    animal_sound(a)

3.2 鸭子类型(Duck Typing)

Python 不强制要求继承关系,只要对象有相应的方法,就可以被多态地调用。

classBird:
deffly(self):
print("鸟儿在飞")

classAirplane:
deffly(self):
print("飞机在飞")

classSuperman:
deffly(self):
print("超人在飞")

defmake_it_fly(obj):
    obj.fly()   # 不关心 obj 是什么类型,只要它有 fly 方法

make_it_fly(Bird())      # 鸟儿在飞
make_it_fly(Airplane())  # 飞机在飞
make_it_fly(Superman())  # 超人在飞

四、多态与抽象基类

Python 的 abc 模块可以定义抽象基类,强制子类实现某些方法,从而实现更规范的多态。

from abc import ABC, abstractmethod

classShape(ABC):
    @abstractmethod
defarea(self):
"""计算面积,子类必须实现"""
pass

classRectangle(Shape):
def__init__(self, width, height):
self.width = width
self.height = height

defarea(self):
returnself.width * self.height

classCircle(Shape):
def__init__(self, radius):
self.radius = radius

defarea(self):
return3.14159 * self.radius ** 2

defprint_area(shape):
print(f"面积: {shape.area()}")

shapes = [Rectangle(4, 5), Circle(3)]
for s in shapes:
    print_area(s)

五、多态在 Python 内置类型中的体现

Python 的内置函数和操作符本身就是多态的典范:

5.1 len() 函数

len() 可以作用于字符串、列表、元组、字典等多种类型。

print(len("hello"))      # 5
print(len([1, 2, 3]))    # 3
print(len({"a": 1, "b": 2}))  # 2

5.2 + 运算符

+ 可以用于数字相加、字符串拼接、列表合并。

print(3 + 5)          # 8(数字相加)
print("Hello" + " " + "World")  # Hello World(字符串拼接)
print([1, 2] + [3, 4])  # [1, 2, 3, 4](列表合并)

5.3 for 循环

for 循环可以遍历任何可迭代对象(实现了 __iter__ 方法的对象)。

for x in"abc":
print(x)
for x in [1, 2, 3]:
print(x)
for x in {"a": 1, "b": 2}:
print(x)

六、多态与接口

在静态类型语言中,多态通常通过接口(interface)实现。Python 虽然没有显式的接口关键字,但可以通过鸭子类型或抽象基类达到类似效果。

6.1 使用鸭子类型(隐式接口)

classUSBDevice:
defconnect(self):
print("USB 设备已连接")

classBluetoothDevice:
defconnect(self):
print("蓝牙设备已连接")

defconnect_device(device):
    device.connect()   # 任何有 connect 方法的对象都可以传入

connect_device(USBDevice())
connect_device(BluetoothDevice())

6.2 使用抽象基类(显式接口)

from abc import ABC, abstractmethod

classConnectable(ABC):
    @abstractmethod
defconnect(self):
pass

classMouse(Connectable):
defconnect(self):
print("鼠标已连接")

classKeyboard(Connectable):
defconnect(self):
print("键盘已连接")

defconnect_device(device: Connectable):
    device.connect()

七、实战案例

7.1 支付系统(不同支付方式)

classPayment:
defpay(self, amount):
raise NotImplementedError

classAlipay(Payment):
defpay(self, amount):
print(f"使用支付宝支付 {amount} 元")

classWechatPay(Payment):
defpay(self, amount):
print(f"使用微信支付 {amount} 元")

classCreditCard(Payment):
defpay(self, amount):
print(f"使用信用卡支付 {amount} 元")

defcheckout(payment_method, amount):
    payment_method.pay(amount)

checkout(Alipay(), 100)
checkout(WechatPay(), 200)
checkout(CreditCard(), 50)

7.2 通知系统

classNotifier:
defsend(self, message):
raise NotImplementedError

classEmailNotifier(Notifier):
defsend(self, message):
print(f"发送邮件: {message}")

classSMSNotifier(Notifier):
defsend(self, message):
print(f"发送短信: {message}")

classPushNotifier(Notifier):
defsend(self, message):
print(f"推送通知: {message}")

defnotify_all(notifiers, message):
for n in notifiers:
        n.send(message)

notifiers = [EmailNotifier(), SMSNotifier(), PushNotifier()]
notify_all(notifiers, "系统维护通知")

7.3 自定义迭代器(实现多态的 __iter__)

classMyRange:
def__init__(self, start, end):
self.start = start
self.end = end

def__iter__(self):
        current = self.start
while current < self.end:
yield current
            current += 1

classMyList:
def__init__(self, items):
self.items = items

def__iter__(self):
returniter(self.items)

defprint_all(iterable):
for item in iterable:
print(item)

print_all(MyRange(1, 5))
print_all(MyList(["a", "b", "c"]))

八、多态与类型提示

Python 的类型提示(Type Hints)可以帮助表达多态接口,但 Python 本身并不强制检查。

from typing import Protocol

classFlyable(Protocol):
deffly(self) -> None:
        ...

classBird:
deffly(self) -> None:
print("鸟飞")

classAirplane:
deffly(self) -> None:
print("飞机飞")

defmake_fly(obj: Flyable) -> None:
    obj.fly()

make_fly(Bird())
make_fly(Airplane())

使用 Protocol(Python 3.8+)可以定义结构化的子类型(类似于 Go 的接口)。


九、总结

  • • 多态 允许同一操作作用于不同对象时产生不同行为。
  • • Python 的多态是基于鸭子类型的:不关心对象类型,只关心对象是否有需要的方法或属性。
  • • 继承 + 方法重写是实现多态的经典方式。
  • • 抽象基类(abc.ABC + @abstractmethod)可以强制子类实现特定方法,实现更规范的多态。
  • • Python 内置函数(如 len()、print())和运算符(如 +、*)都体现了多态思想。

核心思想:面向接口编程,而不是面向实现编程。多态让代码更灵活、更可扩展,是设计可维护系统的关键。

掌握多态,是写出高质量、可扩展 Python 代码的重要一步。它让你可以用统一的接口处理多种不同的对象,而不需要关心具体的类型。

最新文章

随机文章