Python -【多态,抽象类,鸭子类型】的区别及使用

一. 前言

Python中的抽象类、多态和鸭子类型都是实现代码灵活性的机制,但它们之间还是有一些区别的。

二. 三者的区别

  • 抽象类: 要求子类必须实现某些方法,从而规范了子类的实现方式。
  • 多态: 同一个方法可以针对不同类型的对象进行不同的实现,提高了代码的灵活性。
  • 鸭子类型: 不关心对象的类型,只关心对象是否具有某些特定的方法或属性。

三. 概念及示例代码

1. 多态

1.1 多态的三种表现形式:

  • 继承抽象类
    • 耦合度极高,程序的可扩展性极低
  • 继承父类
    • 耦合度高,程序的可扩展性低
  • 鸭子类型
    • 耦合度低,程序的可扩展性高

1.2 多态的目的:

为了在不知道对象具体类型的情况下,统一对象调用方法的规范(名字)

父类: 定制一套统一的规范。(比如: 方法名统一)

子类: 遵循父类的统一的规范。(比如: 子类遵循父类方法名的统一)

1.3 多态的好处:

  1. 增加了程序的灵活性
    以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(people1)
  2. 增加了程序的可扩展性
    通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(people1)去调用

1.4 多态示例代码

class People(Animal): #属于动物的另外一种形态:人def speak(self):print('say hi')def func(people): #对于使用者来说,自己的代码根本无需改动people.speak()people1=People() #实例出一个人func(people1) #甚至连调用方式也无需改变,就能调用人的talk功能'''这样我们新增了一个形态People,由People类产生的实例people1,使用者可以在完全不需要修改自己代码的情况下,使用和猫、狗、猪一样的方式调用people1的speak方法,即func(people1)'''

示例代码二

class Shape:def area(self):passclass Square(Shape):def __init__(self, side):self.side = sidedef area(self):return self.side ** 2class Circle(Shape):def __init__(self, radius):self.radius = radiusdef area(self):return 3.14 * self.radius ** 2def print_area(shape):print(shape.area())s = Square(5)
c = Circle(3)print_area(s)   # 25
print_area(c)   # 28.26

在上述代码中,Shape类是一个基类,定义了一个方法area()SquareCircle类继承了Shape类,并分别实现了自己的area()方法。print_area()函数接受一个Shape类型的参数,不同类型的Shape对象会产生不同的行为,实现了多态。

2. 抽象类

2.1 什么是抽象类?

在python内置的abc模块中,有一个抽象类,让子类必须遵循父类的编写规范。

2.2 如何实现抽象类

  • 父类需要继承abc模块中的metaclass=abc.ABCMeta
  • 在父类的方法中,需要装饰上 abc.abstractmethod

注意:

  • 在python中不推荐使用抽象类。

  • 子类必须按照父类的方法编写规范,缺一不可。(只要父类中有几个抽象方法,子类就必须要定义几个,可以多,但不能少)

2.3 抽象类示例代码

from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef area(self):passclass Square(Shape):def __init__(self, side):self.side = sidedef area(self):return self.side ** 2class Circle(Shape):def __init__(self, radius):self.radius = radiusdef area(self):return 3.14 * self.radius ** 2# 不能实例化Shape
# s = Shape()sq = Square(5)
c = Circle(3)print(sq.area())   # 25
print(c.area())    # 28.26

在上述代码中,Shape类是一个抽象类,定义了一个抽象方法area()SquareCircle类继承了Shape类,并分别实现了自己的area()方法。由于Shape是抽象类,不能直接实例化,只能通过子类进行实例化。

3. 鸭子类型

3.1 什么是鸭子类型

  • python崇尚鸭子类型,不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子。
  • 鸭子类型是多态的一种表现形式。

3.2 为什么要有鸭子类型

不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。所有的类,在定义时都按照统一的规范进行编写。

3.3 鸭子类型示例代码

class Duck:def quack(self):print("Quack")class Person:def quack(self):print("I'm quacking like a duck")def duck_test(obj):obj.quack()d = Duck()
p = Person()duck_test(d)    # Quack
duck_test(p)    # I'm quacking like a duck

在上述代码中,DuckPerson类都有一个quack()方法,duck_test()函数接受一个对象参数,只要该对象有quack()方法即可,不关心其具体类型,实现了鸭子类型。

四. 总结:

  • 抽象类是一种特殊的类,不能被实例化。它的作用是规范子类的行为。
  • 多态是一种基于继承的特性,同一个方法可以针对不同类型的对象进行不同的实现。
  • 鸭子类型是一种动态类型机制,关注对象的行为而不关注其类型,只要一个对象实现了特定的接口,就可以被当做该接口的实现对象。

以上就是关于Python -【多态,抽象类,鸭子类型】的区别及使用介绍,希望对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/79701.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机网络】Tcp详解

文章目录 前言Tcp协议段格式TCP的可靠性面向字节流应答机制超时重传流量控制滑动窗口(重要)拥塞控制延迟应答捎带应答标志位具体标志位三次握手四次挥手粘包问题TCP异常情况listen的第二个参数 前言 前面我们学习了传输层协议Udp,今天我们一…

invalid use of incomplete type ‘class Ui::xxx‘

MainWindow 引用自定义窗口报错:invalid use of incomplete type class Ui::xxx mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include "form.h" form.cpp #include "form.h" #include "…

使用FFmpeg+ubuntu系统转化flac无损音频为mp3

功能需求如上题,我们来具体的操作一下: 1.先在ubuntu上面安装FFmpeg:sudo apt install ffmpeg 2.进入有flac音频文件的目录使用下述命令: ffmpeg -i test.FLAC -c:a libmp3lame -q:a 2 output.mp3 3.如果没有什么意外的话,你就能看到你的文件夹里面已经有转化好的mp3文件了 批…

ubuntu中如何用docker下载华为opengauss数据库(超简单)

ubuntu中如何下载华为opengauss数据库 前言一、安装docker1.方法一:2.方法二 二、拉取openguass镜像三、创建容器四、连接数据库 ,切换到omm用户 ,用gsql连接到数据库五.最后用DateGrip远程连接测试(1)选择数据源(2)查看虚拟机ip地…

#循循渐进学51单片机#定时器与数码管#not.4

1、熟练掌握单片机定时器的原理和应用方法。 1)时钟周期:单片机时序中的最小单位,具体计算的方法就是时钟源分之一。 2)机器周期:我们的单片机完成一个操作的最短时间。 3)定时器:打开定时器“储存寄存器…

Python提取JSON数据中的键值对并保存为.csv文件

本文介绍基于Python,读取JSON文件数据,并将JSON文件中指定的键值对数据转换为.csv格式文件的方法。 在之前的文章Python提取JSON文件中的指定数据并保存在CSV或Excel表格文件内(https://blog.csdn.net/zhebushibiaoshifu/article/details/132…

Windows PostgreSql 创建多个数据库目录

1 使用默认用户Administrator 1.1初始化数据库目录 E:\Program Files\PostgreSQL\13> .\bin\initdb -D G:\DATA\pgsql\data3 -W -A md5 1.2连接数据库 这时User为Administrator,密码就是你刚才设置的,我设置的为123456,方便测试。 2 添加…

黑马JVM总结(九)

(1)StringTable_调优1 我们知道StringTable底层是一个哈希表,哈希表的性能是跟它的大小相关的,如果哈希表这个桶的个数比较多,元素相对分散,哈希碰撞的几率就会减少,查找的速度较快&#xff0c…

Meta分析核心技术

Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…

代码随想录算法训练营19期第53天

1143.最长公共子序列 视频讲解:动态规划子序列问题经典题目 | LeetCode:1143.最长公共子序列_哔哩哔哩_bilibili 代码随想录 初步思路:动态规划。 总结: dp[i][j] :长度为[0, i - 1]的字符串A与长度为[0, j - 1]…

【微服务】六. Nacos配置管理

6.1 Nacos实现配置管理 配置更改热更新 在nacos左侧新建配置管理 Data ID:就是配置文件名称 一般命名规则:服务名称-环境名称.yaml 配置内容填写:需要热更新需求的配置 配置文件的id:[服务名称]-[profile].[后缀名] 分组&#…

Vuex详解:Vue.js的状态管理方案

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

启动微服务,提示驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接

说明:启动一些微服务后,一直在报下面这个错误; com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“The server selected protocol version TLS10 is not acc…

【学习笔记】CF1770F Koxia and Sequence

发现每个位置是等价的,这样如果 n n n为偶数那么答案是 0 0 0,否则为所有方案数中 a 1 a_1 a1​的异或和 发现题目设计的非常巧妙,加上 ( OR i 1 n a i ) ⊆ y (\text{OR}_{i1}^n a_i)\subseteq y (ORi1n​ai​)⊆y 的限制过后&#xff0c…

uniapp抽取组件绑定事件中箭头函数含花括号无法解析

版本: "dcloudio/uni-ui": "^1.4.27", "vue": "> 2.6.14 < 2.7"... 箭头函数后含有花括号的时候, getData就拿不到val参数 , 解决办法就是去除花括号 // 错误代码: <SearchComp change"(val) > { getData({ val …

Layui快速入门之第十节 表单

目录 一&#xff1a;基本用法 二&#xff1a;输入框 普通输入框 输入框点缀 前置和后置 前缀和后缀 动态点缀 密码显隐 内容清除 自定义动态点缀 点缀事件 三&#xff1a;复选框 默认风格 标签风格 开关风格 复选框事件 四&#xff1a;单选框 普通单选框 自…

8.Spring EL与ExpressionParser

Spring EL与ExpressionParser 文章目录 Spring EL与ExpressionParser介绍**使用SpEL来计算评估文字字符串表达式**使用SpEL来计算评估 bean 属性 – “item.name” 介绍 Spring表达式语言(SpEL)支持多种功能&#xff0c;并且可以测试这个特殊的“ExpressionParser”接口的表达…

跨域问题解决方案(三种)

Same Origin Policy同源策略&#xff08;SOP&#xff09; 具有相同的Origin&#xff0c;也即是拥有相同的协议、主机地址以及端口。一旦这三项数据中有一项不同&#xff0c;那么该资源就将被认为是从不同的Origin得来的&#xff0c;进而不被允许访问。 Cross-origin resource…

docker快速安装redis,mysql,minio,nacos等常用软件【持续更新】

redis ①拉取镜像 docker pull redis② 创建容器 docker run -d --name redis --restartalways -p 6379:6379 redis --requirepass "PASSWORD"–requirepass “输入你的redis密码” nacos ①&#xff1a;docker拉取镜像 docker pull nacos/nacos-server:1.2.0②…

Jsoup | Document | HTML解析器

Jsoup 一、获取 <p>标签下的所有图片 一、获取 <p>标签下的所有图片 <p> <img style"max-width: 100%;" src"http://image.svipjf.cn/1678271098160-480_01.jpg"/><img src"http://image.svipjf.cn/1678271097994-480_02…