Python 入门教程(7)面向对象 | 7.6、多态

文章目录

前言:

在面向对象编程(OOP)中,多态(Polymorphism)是一种非常重要的概念,多态就是同一个一种接口,根据调用对象的不同而表现出不同的行为。Python作为一门动态类型语言,其多态性实现起来非常自然和直观,因为它天生支持动态绑定和鸭子类型(Duck Typing)。

一、多态

1、鸭子类型

鸭子类型是一种动态类型系统,其核心思想是关注对象能够做什么(即它们的方法和行为),而不是它们是什么(即它们的类型或类)。这意味着在Python中,你不需要显式地声明一个对象属于某个特定的类或者实现了某个接口,只要它拥有你需要的方法,你就可以像使用那个类型的对象一样来使用它。

示例:

假设有一个场景,需要处理不同类型的图形对象,并计算它们的面积。可以定义一个Shape基类(尽管在鸭子类型中这不是必需的),然后创建几个继承自Shape的子类(如CircleRectangle),但实际上,并不需要这样做。只需要确保每个对象都有一个area()方法即可。

python 复制代码
class Circle:  
    def __init__(self, radius):  
        self.radius = radius  
  
    def area(self):  
        return 3.14 * self.radius ** 2  
  
class Rectangle:  
    def __init__(self, width, height):  
        self.width = width  
        self.height = height  
  
    def area(self):  
        return self.width * self.height  
  
# 假设我们还有一个非图形对象,但它也有area方法  
class AreaCalculator:  
    def __init__(self, base_area):  
        self.base_area = base_area  
  
    def area(self):  
        return self.base_area * 2  # 假设这是某种特定的计算方式  
  
# 使用鸭子类型  
def calculate_area(shape):  
    return shape.area()  
  
circle = Circle(5)  
rectangle = Rectangle(4, 5)  
calculator = AreaCalculator(10)  
  
print(calculate_area(circle))    # 调用Circle的area方法  
print(calculate_area(rectangle)) # 调用Rectangle的area方法  
print(calculate_area(calculator))# 调用AreaCalculator的area方法,尽管它不是图形对象

鸭子类型的优点:

  • 灵活性: 鸭子类型使得Python程序更加灵活,因为它允许开发者在不修改现有代码的情况下,轻松地添加新的类型或类。只要新类型遵循了某些协议(即拥有特定的方法或属性),它就可以无缝地集成到现有系统中。
  • 简洁性: 由于Python不要求显式地声明类型或接口,代码变得更加简洁。开发者可以专注于实现功能,而不是编写大量的类型声明和接口定义。
  • 动态性: Python的动态特性与鸭子类型相辅相成,使得程序能够在运行时根据需要改变其行为。这种能力在编写大型、复杂的系统时尤其有用。

2、实现多态的机制

Python中可以通过多种方式实现多态,下面介绍下常用的方式

2.1、鸭子类型

鸭子类型强调的是对象的行为,而不是它们的类型或类。这意味着,只要对象具有我们期望的方法,就可以以统一的方式调用它们,而无需关心它们具体属于哪个类。

示例:

python 复制代码
# 定义一个接口(虽然Python中没有显式的接口定义,但我们可以通过文档或约定来模拟)  
# 假设我们有一个可以"执行"的接口,它应该有一个名为execute的方法  
  
class Executable:  
    """  
    这是一个模拟的接口,用于说明可执行对象应该具有execute方法。  
    注意:Python中实际上并不需要显式定义这样的接口类。  
    """  
    def execute(self):  
        raise NotImplementedError("子类必须实现这个方法")  
  
# 定义两个实现了"execute"方法的类  
class Script:  
    def execute(self):  
        print("Running a script...")  
  
class Command:  
    def execute(self):  
        print("Executing a command...")  
  
# 定义一个函数,它接受任何具有execute方法的对象  
def run_anything(executable):  
    executable.execute()  
  
# 创建不同类型的对象,它们都实现了execute方法  
script = Script()  
command = Command()  
  
# 使用多态的方式调用它们  
run_anything(script)  # 输出: Running a script...  
run_anything(command) # 输出: Executing a command...  
  
# 注意:我们甚至可以传入一个没有继承自Executable,但具有execute方法的对象  
class CustomExecutable:  
    def execute(self):  
        print("Executing something custom...")  
  
custom = CustomExecutable()  
run_anything(custom)  # 输出: Executing something custom...

2.2、继承与重写

在Python中,继承和方法重写(或称为方法覆盖)是实现多态性的另一种方式,尽管从技术上讲,多态性主要是通过动态类型系统(即"鸭子类型")来实现的,但继承和方法重写为多态性提供了额外的结构和灵活性。

示例:

python 复制代码
# 定义一个基类(接口)  
class Shape:  
    def draw(self):  
        raise NotImplementedError("子类必须实现这个方法")  
  
# 定义两个子类,它们继承自Shape类并重写draw方法  
class Circle(Shape):  
    def draw(self):  
        print("Drawing a circle...")  
  
class Rectangle(Shape):  
    def draw(self):  
        print("Drawing a rectangle...")  
  
# 定义一个函数,它接受Shape类型的对象作为参数  
def draw_shape(shape):  
    shape.draw()  
  
# 创建Circle和Rectangle对象  
circle = Circle()  
rectangle = Rectangle()  
  
# 使用多态的方式调用draw方法  
draw_shape(circle)    # 输出: Drawing a circle...  
draw_shape(rectangle) # 输出: Drawing a rectangle...

3、Python多态的优势

  • 灵活性: Python的多态允许开发者编写灵活且可复用的代码,因为你可以轻松地扩展程序以支持新的类型,而无需修改现有的代码。
  • 可扩展性: 通过遵循相同的接口(即具有相同的方法签名),新的类可以轻松地集成到现有的程序中,而不需要对现有代码进行大的修改。
  • 代码清晰度: 多态使得代码更加清晰易懂,因为它减少了类型检查和条件语句的需要,使得代码更加简洁。

4、总结

Python通过其动态类型和鸭子类型机制,自然地支持多态性。这使得Python在编写可重用、可扩展和灵活的代码时非常强大。在Python中利用多态,可以极大地提高代码的可读性和可维护性,同时也使得程序更加易于扩展和修改

相关推荐
V_fanglue370516 分钟前
qmt量化交易策略小白学习笔记第67期【qmt编程之获取ETF申赎清单】
大数据·前端·数据库·笔记·python·学习·区块链
好奇的菜鸟21 分钟前
探索 JUnit 5:下一代 Java 测试框架
java·开发语言·junit
林小果121 分钟前
桥接模式
java·开发语言·设计模式
FreakStudio22 分钟前
全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码
python·嵌入式·面向对象·电子diy
@月落1 小时前
PHP API 框架:构建高效API的利器
开发语言·php
软糖工程0011 小时前
正则表达式【详细解读】
大数据·前端·爬虫·python·学习·正则表达式·数据分析
程序员的战歌1 小时前
django drf to_internal_value
python·django
程序员的战歌1 小时前
django drf 分页器
python·django
情书2 小时前
Java调用第三方接口、http请求详解,一文学会
java·开发语言·http
Stark、2 小时前
C++入门day5-面向对象编程(终)
开发语言·c++·后端·学习方法