Python 多态

在 Python 中,多态(Polymorphism)是 “面向对象编程(OOP)” 的三大特性之一,另外两个是封装和继承。多态指的是同一个方法在不同的对象上,可能会有不同的行为。简单来说就是:一个接口,多种实现

Python 多态是什么?

在了解多态之前,我们先来回顾一下 Python 中的 “继承”。继承允许我们定义一个基类,然后其他类(派生类)可以继承这个基类,并获得基类的属性和方法。而多态则是在继承的基础上,允许不同的派生类对同一方法有不同的实现。

举个简单例子,我们有一个 “动物” 的基类,它有一个 speak() 方法。对于不同的动物来说,speak() 方法会有不同的行为,比如:狗会 “汪汪叫”,猫会 “喵喵叫”,鸭子会 “嘎嘎叫”。speak() 方法根据调用的对象不同,表现出不同的行为,这就是多态的体现。

Python 多态

Python 多态的实现

Python 是一种动态类型语言,它天然支持多态。我们不需要像 Java 或 C++ 那样显式地声明接口或虚函数。只要对象拥有相同的方法名,就可以实现多态。

示例 1:Python 实现简单多态

class Animal:
    def speak(self):
        print('动物发出声音')

class Dog(Animal):
    def speak(self):
        print('汪汪叫')

class Cat(Animal):
    def speak(self):
        print('喵喵叫')

class Duck(Animal):
    def speak(self):
        print('嘎嘎叫')

# 定义一个函数,接受 Animal 类型的对象
def make_animal_speak(animal):
    animal.speak()

# 创建不同动物的对象
dog = Dog()
cat = Cat()
duck = Duck()
animal = Animal()

# 调用函数,传入不同类型的动物对象
make_animal_speak(animal)
make_animal_speak(dog)
make_animal_speak(cat)
make_animal_speak(duck)

运行结果如下。

动物发出声音
汪汪叫
喵喵叫
嘎嘎叫

分析:

在这个例子中,我们定义了一个 Animal 基类,它有一个 speak() 方法。Dog、Cat 和 Duck 这 3 个类都继承自 Animal,并且都重写了 speak() 方法,提供了各自特定的实现。

然后,我们定义了一个 make_animal_speak() 函数,它接受一个 animal 参数。在这个函数内部,我们调用 animal.speak()。

当传入 Dog、Cat 或 Duck 的实例时,make_animal_speak() 函数会根据实际传入对象的类型,来调用其对应的 speak() 方法。

上面例子体现的就是多态。在同一个 make_animal_speak() 函数,对于不同的对象会表现出不同的行为。

Python 多态的应用

多态在实际开发中非常有用,它能够提高代码的灵活性、可扩展性和可维护性。

示例 2:处理不同类型的支付方式

class Payment:
    def pay(self, amount):
        raise NotImplementedError('子类必须实现 pay() 方法')

class Alipay(Payment):
    def pay(self, amount):
        print(f'支付宝支付 {amount} 元')

class WechatPay(Payment):
    def pay(self, amount):
        print(f'微信支付 {amount} 元')

class BankCardPay(Payment):
    def pay(self, amount):
        print(f'银行卡支付 {amount} 元')

def process_payment(payment_method, amount):
    payment_method.pay(amount)

alipay = Alipay()
wechat_pay = WechatPay()
bank_card_pay = BankCardPay()

process_payment(alipay, 100)
process_payment(wechat_pay, 50)
process_payment(bank_card_pay, 200)

运行结果如下。

支付宝支付 100 元
微信支付 50 元
银行卡支付 200

分析:

假设我们正在开发一个电商平台,需要处理多种支付方式(如支付宝、微信支付、银行卡支付)。我们可以定义一个统一的支付接口,然后每种支付方式都实现这个接口。

在这个例子中,Payment 类定义了一个 pay() 方法的接口(虽然 Python 没有严格的接口定义,但 NotImplementedError 强制子类实现)。Alipay、WechatPay 和 BankCardPay 这 3 个类都继承 Payment 类,并实现了自己的 pay() 方法。

process_payment() 函数可以接受任何 Payment 类型的对象,并调用其 pay() 方法,从而实现不同支付方式的统一处理。

示例 3:多态实现 “绘制图形”

import math

class Shape:
    def area(self):
        raise NotImplementedError('子类必须实现 area() 方法')

    def draw(self):
        raise NotImplementedError('子类必须实现 draw() 方法')

# 绘制圆形
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return math.pi * self.radius ** 2

    def draw(self):
        print(f'绘制圆形,半径为 {self.radius},面积为 {self.area():.2f}')

# 绘制矩形
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

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

    def draw(self):
        print(f'绘制矩形,宽度为 {self.width},高度为 {self.height},面积为 {self.area():.2f}')

def render_shape(shape):
    shape.draw()

circle = Circle(5)
rectangle = Rectangle(4, 6)

render_shape(circle)
render_shape(rectangle)

运行结果如下。

绘制圆形,半径为 5,面积为 78.54
绘制矩形,宽度为 4,高度为 6,面积为 24.00

分析:

在 Shape 类中,我们定义了 area() 和 draw() 方法作为图形的通用接口。Circle 和 Rectangle 分别实现了这些方法,提供了各自形状的计算面积和绘制逻辑。

render_shape() 函数可以处理任何 Shape 类型的对象,并调用其 draw() 方法,从而实现了不同图形的统一绘制。

上一篇: Python 元类

下一篇: Python 包与模块

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号