当前位置: 首页 > news >正文

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

文章目录

  • 一、多态
    • 1、鸭子类型
    • 2、实现多态的机制
      • 2.1、鸭子类型
      • 2.2、继承与重写
    • 3、Python多态的优势
    • 4、总结

前言:

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

一、多态

1、鸭子类型

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

示例:

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

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中没有显式的接口定义,但我们可以通过文档或约定来模拟)  
# 假设我们有一个可以“执行”的接口,它应该有一个名为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中,继承和方法重写(或称为方法覆盖)是实现多态性的另一种方式,尽管从技术上讲,多态性主要是通过动态类型系统(即“鸭子类型”)来实现的,但继承和方法重写为多态性提供了额外的结构和灵活性。

示例:

# 定义一个基类(接口)  
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中利用多态,可以极大地提高代码的可读性和可维护性,同时也使得程序更加易于扩展和修改

相关文章:

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

文章目录 一、多态1、鸭子类型2、实现多态的机制2.1、鸭子类型2.2、继承与重写 3、Python多态的优势4、总结 前言: 在面向对象编程(OOP)中,多态(Polymorphism)是一种非常重要的概念,多态就是同一…...

Cilium + ebpf 系列文章-什么是ebpf?(一)

前言: 这篇非常非常干,很有可能读不懂。 这里非常非常推荐,建议使用Cilium官网的lab来辅助学习!!!Resources Library - IsovalentExplore Isovalents Resource Library, your one-stop destination for ins…...

RabbitMQ08_保证消息可靠性

保证消息可靠性 一、生产者可靠性1、生产者重连机制(防止网络波动)2、生产者确认机制Publisher Return 确认机制Publisher Confirm 确认机制 二、MQ 可靠性1、数据持久化交换机、队列持久化消息持久化 2、Lazy Queue 惰性队列 三、消费者可靠性1、消费者…...

恶意Bot流量识别分析实践

1、摘要 随着互联网的发展,自动化工具和脚本(Bots)的使用越来越普遍。虽然一些善意 Bots 对于网站的正常运行和数据采集至关重要,但恶意 Bots 可能会对网站带来负面影响,如爬取敏感信息、恶意注册、刷流量等。因此&am…...

Java2 实用教程(第6版)习题2 第四题

【源文件的命名与书中的不同】 四、阅读程序题 1、上机运行下列程序&#xff0c;注意观察输出的结果。 public class E2_1 {public static void main(String args[]){for(int i20302;i<20322;i){System.out.println((char) i);}} } 运行结果&#xff1a; 低 住 佐 佑 佒…...

HashMap和ConcurrentHashMap的区别

1.是什么 HashMap和ConcurrentHashMap都是Java集合框架中的成员&#xff0c;它们用于存储键值对&#xff0c;但它们在并发场景下的表现和行为有很大的不同。以下是它们之间的一些主要区别&#xff1a; 1. 并发安全性 HashMap: HashMap不是线程安全的。如果多个线程同时访问Has…...

css 下拉框展示:当hover的时候展示下拉框 z-index的用法解释

代码如下&#xff1a; <template><div class"outer"><div class"left"></div><div class"aTest2"><div class"box">显示方框</div><div class"aTest3"></div></…...

spring装配笔记

spring装配是个大课题&#xff0c;能懂一点是一点吧。 关于代码链路&#xff0c;最后的方式就是倒序摸索&#xff0c;正序那么多逻辑&#xff0c;没有一百万也差不多少&#xff0c;所以就用倒序。 .(点号)和#井号是一个意思&#xff0c;下面代码可能不详细区分&#xff0c;复…...

vscode【实用插件】Notes 便捷做笔记

安装 在 vscode 插件市场的搜索 Notes点 安装 安装成功后&#xff0c;vscode 左侧栏会出现 使用 初次使用 需先选择一个本地目录 重启 vscode 后&#xff0c;得到 切换笔记目录 新建笔记 快捷键为 Alt N 默认会创建 .md 文件 配合插件 Markdown Preview Enhanced 预览 .md…...

中间件:maxwell、canal

文章目录 1、底层原理&#xff1a;基于mysql的bin log日志实现的&#xff1a;把自己伪装成slave2、bin log 日志有三种模式&#xff1a;2.1、statement模式&#xff1a;2.2、row模式&#xff1a;2.3、mixed模式&#xff1a; 3、maxwell只支持 row 模式&#xff1a;4、maxwell介…...

postman控制变量和常用方法

1、添加环境&#xff1a; 2、环境添加变量&#xff1a; 3、配置不同的环境&#xff1a;local、dev、sit、uat、pro 4、 接口调用 5、清除cookie方法&#xff1a; 6、下载文件方法&#xff1a;...

Spring Boot 中整合 Kafka

在 Spring Boot 中整合 Kafka 非常简单&#xff0c;Spring Kafka 提供了丰富的支持&#xff0c;使得我们可以轻松地实现 Kafka 的生产者和消费者。下面是一个简单的 Spring Boot 整合 Kafka 的示例。 1. 添加依赖 首先&#xff0c;在 pom.xml 中添加 Spring Kafka 的依赖&#…...

什么是开放式耳机?具有什么特色?非常值得入手的蓝牙耳机推荐

开放式耳机是当下较为热门的一种耳机类型。它具有以下特点&#xff1a; 设计结构&#xff1a; 呈现开放式的构造&#xff0c;不会完全堵住耳道。如此一来&#xff0c;外界声音能够较容易地被使用者听到&#xff0c;在使用耳机时可以保持对周围环境的察觉。比如在户外&#xf…...

编译 FFmpeg 以支持 AV1 编解码器以及其他硬件加速选项(如 NVENC、VAAPI 等)

步骤 1: 安装必要的依赖 sudo apt update sudo apt install -y \autoconf automake build-essential cmake git libass-dev libfreetype6-dev \libsdl2-dev libtool libva-dev libvdpau-dev libxcb1-dev libxcb-shm0-dev \libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-…...

解释一下Java中的多线程。如何创建一个新的线程?

在Java中&#xff0c;多线程是一种机制&#xff0c;允许一个程序同时执行多个任务或处理。每个任务被称为一个线程。 这种并行执行可以极大地提高应用程序的效率和响应速度。 例如&#xff0c;在开发一个桌面应用程序时&#xff0c;你可以使用一个线程来更新用户界面&#xf…...

Java语言程序设计基础篇_编程练习题**18.30 (找出单词)

题目&#xff1a;**18.30 (找出单词) 编写一个程序&#xff0c;递归地找出某个目录下的所有文件中某个单词出现的次数。从命令行如下传递参数&#xff1a; java Exercise18_30 dirName word 习题思路 &#xff08;读取路径方法&#xff09;和18.28题差不多&#xff0c;把找…...

MyBatis中 #{} 和 ${} 的区别

1. #{id}&#xff08;参数占位符&#xff09; 作用: 使用 #{id} 时&#xff0c;MyBatis 会将 id 参数绑定为 JDBC 的参数。这种方式能够有效防止 SQL 注入攻击&#xff0c;因为它会进行参数的预处理&#xff0c;将参数值作为数据类型的绑定&#xff0c;而不是直接插入到 SQL 语…...

Android Perfetto 学习

1、如何抓取性能日志 方式1、通过手机里的System Tracing抓取 1、点击Settings->System->Developer options->System Tracing->Record trace 打开 2、操作完成后&#xff0c;点击Settings->System->Developer options->System Tracing->Record trace…...

ES数据的删除与备份

背景 需要删除索引下满足指定条件的文档数据&#xff0c;并将删除的数据进行备份。 操作步骤 新建索引 该索引结构与映射关系与原索引一致 查看原索引设置 GET /tb/_settings结果&#xff1a; {"tb" : {"settings" : {"index" : {"ro…...

论文解读《Object-Centric Learning with Slot Attention》

系列文章目录 文章目录 系列文章目录论文细节理解 1. 研究背景2. 论文贡献3. 方法框架3.1 Slot Attention模块3.2 无监督对象发现架构 4. 研究思路5. 实验6. 限制 论文细节理解 supervised property prediction tasks是什么&#xff1f; Supervised property prediction tasks…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

Vue 3 + WebSocket 实战:公司通知实时推送功能详解

&#x1f4e2; Vue 3 WebSocket 实战&#xff1a;公司通知实时推送功能详解 &#x1f4cc; 收藏 点赞 关注&#xff0c;项目中要用到推送功能时就不怕找不到了&#xff01; 实时通知是企业系统中常见的功能&#xff0c;比如&#xff1a;管理员发布通知后&#xff0c;所有用户…...

算法—栈系列

一&#xff1a;删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {stack<char> st;for(int i 0; i < s.size(); i){char target s[i];if(!st.empty() && target st.top())st.pop();elsest.push(s[i]);}string ret…...