多态

问起面向对象的三大特性,几乎每个人都能对答如流:封装、继承、多态。今天我们就要来说一说 Python 中的多态。所谓多态:就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

我在《Python 中的设计模式详解之:策略模式》一文中详细描述了策略模式的实现,而策略模式就是典型的多态应用。

之前的代码我就不贴了,大家可以去原文中查看。我依然还是以商品折扣的经典举例。策略模式一文中,传统的策略模式实现方式我也是用 Python 代码实现的,在 java 或 C# 等语言中,实现方式也差不多。以下是 C# 代码,我只列了个架子:interface Promotion

{

double discount(Order order);

}

class FidelityPromo : Promotion  // 第一个具体策略

{

// 为积分为1000或以上的顾客提供5%折扣

public double discount(Order order){

...

}

}

class BulkItemPromo : Promotion // 第二个具体策略

{

//单个商品为20个或以上时提供10%折扣

public double discount(Order order){

...

}

}

class LargeOrderPromo : Promotion // 第三个具体策略

{

//订单中的不同商品达到10个或以上时提供7%折扣

public double discount(Order order){

...

}

}

可以看到,首先要有一个接口(Promotion),然后各个策略去实现这个接口。然而,Python 语言没有 interface 关键字,就是说,Python 里没有像 java、C# 一样的接口。

在策略模式一文的实现中,使用了抽象基类(Abstract Base Class,ABC)来实现接口,这主要是为了写法上看起来和 java、C# 等语言更加的像,易于有这些语言基础的同学理解和对比。

抽象基类是在 Python 语言诞生 15 年后,Python 2.6 才引入的。这里我们不详细介绍抽象基类,因为即便现在也很少有代码使用抽象基类。对于多态,Python 有更好的实现方式——鸭子类型(duck typing)。

协议和鸭子类型所谓 鸭子类型 就是:如果一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么它就是鸭子。这个概念的名字来源于 James Whitcomb Riley 提出的鸭子测试。

初次看到这个描述的小伙伴一定一头雾水,为了理解鸭子类型,我们不得不提到另一个名词——协议。在面向对象编程中,协议是非正式的接口,是一组方法,只由文档和约定定义,因此,协议不能像正式接口那样施加强制性约束。而 Python 的哲学就是尽量支持基本协议。

翻译成人话,就是:Python 中没有接口,在需要使用接口的地方,就用协议代替。所谓协议,其实就是一组方法,和接口中定义的方法一个意思。只不过协议是不是强制性的约定,如果你不遵守协议,那么也没关系,运行时报错就是了。

这样就好理解鸭子类型了,“如果一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子” 这就表示已经遵守了协议,“那么它就是鸭子”,意味着你可以在其他用到“鸭子”的地方,用“这只鸟”替换。这不就是多态吗?

用“鸭子类型”来实现策略模式也很简单,删掉抽象基类就可以了。(这就是为什么抽象基类很少使用的原因,因为删掉代码也一样正确啊。)有兴趣的小伙伴可以自己尝试一下代码。

Python 中的协议举例

Python 中有很多的协议,比如迭代器协议,任何实现了 __iter__ 和__next__ 方法的对象都可称之为迭代器,但对象本身是什么类型不受限制,这得益于鸭子类型。from collections import Iterable

from collections import Iterator

class MyIterator:

def __iter__(self):

pass

def __next__(self):

pass

print(isinstance(MyIterator(), Iterable))

print(isinstance(MyIterator(), Iterator))

输出:True

True

结语

鸭子类型是编程语言中动态类型语言中的一种设计风格,一个对象的特征不是由父类决定,而是通过对象的方法决定的。

Python 不是不支持多态,而是 Python 本身就是一门多态的语言。

java 鸭子类_Python:多态、协议和鸭子类型相关推荐

  1. python鸭制作类代码_Python实现多态、协议和鸭子类型的代码详解

    多态 问起面向对象的三大特性,几乎每个人都能对答如流:封装.继承.多态.今天我们就要来说一说 Python 中的多态. 所谓多态:就是指一个类实例的相同方法在不同情形有不同表现形式.多态机制使具有不同 ...

  2. python有多态特性吗_Python:多态、协议和鸭子类型

    多态 问起面向对象的三大特性,几乎每个人都能对答如流:封装.继承.多态.今天我们就要来说一说 Python 中的多态. 所谓多态:就是指一个类实例的相同方法在不同情形有不同表现形式.多态机制使具有不同 ...

  3. java 鸭子类_Java中实现鸭子类型机制

    "当看到一只鸟走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只鸟就可以被称为鸭子."[引用维基] 一般而言,鸭子类型机制常见/用于动态语言,如Python.Ruby.JS.来 ...

  4. python鸭制作类代码_Python动态语言与鸭子类型详解

    今天来说说编程语言中的动态类型语言与鸭子类型. 动态语言 维基百科对动态语言的定义: 动态编程语言是一类在运行时可以改变其结构的语言:例如新的函数.对象.甚至代码可以被引进,已有的函数可以被删除或是其 ...

  5. python鸭子类型与协议理解

    鸭子类型 定义 在维基百科中的准确定义是'是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定' 个人理 ...

  6. python 鸭子类型及三大特性

    python 中一切皆对象. 先说 说面向对象语言三大特性:封装.继承.多态. 1.封装分两个层面 第一层面:创建类和对象时,分别创建两人者的名称空间,只能通过类名加"."或者ob ...

  7. 用python画小鸭_python中的鸭子类型(协议)和接口

    定义 1. 接口(interface) 学过静态语言的同学一定对接口的概念并不陌生,它类似于我们家里用的插座标准,要用电器时,我们得先查看对应的插头是否和插座孔匹配.也正因为此,接口给我们提供了很大的 ...

  8. python 多态 协议 鸭子类型

    接口(python 中的协议)的多种不同的实现方式即为多态.多态的作用,就是为了类在继承和派生的时候,保证使用"家谱"中任一类的实例的某一属性时的正确调用. from abc im ...

  9. python鸭制作类代码_python之鸭子类型

    python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型. 在程序设计中,鸭子类型是动态类型的一种风格,不是由继承特定的类或实现特定的接口,而是当前的方法和属性的集合决定,鸭子 ...

最新文章

  1. 清华博士宅家太无聊,给猫咪讲函数
  2. 软件测试 图覆盖,软件测试(四)——图覆盖
  3. SAP BDT业务数据工具集的开发原理及应用实例
  4. [*leetcode 5] Longest Palindromic Substring
  5. C++基础知识学习笔记
  6. Android 原生通知Notification 写法
  7. 自定义线程池-线程类和任务类代码实现
  8. DataSet用法详细
  9. 【无码专区5】01串(大讨论+构造)
  10. 编写声卡驱动(框架)
  11. 前端学习(1924)vue之电商管理系统电商系统之权限的渲染方式
  12. LeetCode 720. 词典中最长的单词(Trie树)
  13. 欢乐大作战服务器维护,欢乐大作战
  14. 计算机学模型,计算机数学模型.pdf
  15. rabbitmq的web管理界面-密码管理
  16. 09.5. 机器翻译与数据集
  17. 微信小程序获取rich-text(富文本)渲染内容高度,rich-text(富文本)里img 样式设置
  18. conda.core.subdir_data.Response304ContentUnchanged CondaHTTPError: HTTP 000 CONNECTION FAILED
  19. 气泡shader_Android超简单气泡效果
  20. 「HTML+CSS」--自定义加载动画【027】

热门文章

  1. RGB颜色规律小研究
  2. 品牌数字化转型|借势营销节点,3 招解锁品牌营销力
  3. revit二开之过滤族(Family)
  4. EV3文件打不开,闪退怎么办(完美解决,无弹窗,无警告)
  5. 判断两个矩形是否重叠
  6. 电脑上不了网,网络协商速率只有10M?
  7. SpringBoot 轻松搞定数据验证 (一)
  8. vue 中的el表达式_解释el页面数据表达式
  9. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java社区闲置物品交易平台z10mc
  10. sqoop 导出hive数据到MySQL数据库当中