如果一只动物走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只动物就可以被称为鸭子。

许多编程语言都支持 Duck Typing ,通常 Duck Typing 是动态编程语言用来实现多态的一种方式。

在理解 Duck Typing 前,先看一张图片,这是曾经一度很火的大黄鸭

先问一个比较考三观的问题:图片中的大黄鸭,它是不是一只鸭子呢?

这个问题,得看你从哪个角度去看,如果从人们常识的认知中的角度去看,它显然不是一只鸭子,因为它连最基本的生命都没有。

但是从 Duck Typing 的角度来看,它就是一只鸭子!

Duck Typing 的原话是,走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么它就是一只鸭子。

这个原话是可以灵活理解的,就看我们怎么定义鸭子的行为,我们可以说,能浮在水上游的,黄色的,可爱的就是鸭子,那么,图片中的大黄鸭,它就是一只鸭子!

这就是所谓的 Duck Typing,它只关心事物的外部行为而非内部结构。它并不关心你这只鸭子是长肉的还是充气的。

在编程中,也常常用这种方式来描述事物。那么不同的编程语言中,Duck Typing 是怎么样实现的呢?

1. Python 中的 Duck Typing

先看一个函数:

def download(fetcher):

return fetcher.get("http://xxx");

有一个 download 函数,传过来一个 fetcher 参数,fetcher 是可以获取一个 url 链接的资源的。

这个 fetcher 就是一个 Duck Typing 的对象,使用者约定好这个 fetcher 会有一个 get 函数就可以了。

显然这个 download 函数会有以下问题:

运行时才知道传入的 fetcher 有没有 get 函数。那么站在 download 函数的使用者的角度上看,我怎么知道需要给 fetcher 实现 get 方法呢?我不可能去阅读 download 函数的代码,实际情况中,可能 download 函数的代码很长,可能 fetcher 不只要实现 get 方法,还有其它方法需要实现。通常这种情况需要通过加注释来说明。

2. C++ 中的 Duck Typing

C++ 不是动态语言,但是它也能支持 Duck Typing,它是通过模板来支持的。

示例代码:

template

string download(const F& fetcher){

return fetcher.get("http://xxxx")

}

这段代码与 Python 的实现方法类似,这个 fetcher 随便什么类型都可以,只要实现一个 get 方法,就能通过编译。

那么这种实现方法有什么缺点呢,就是,编译时,才知道传入的 fetcher 有没有 get 方法。

但它比 python 好一点了,python 是运行时才知道,C++ 是编译时就知道。

同样,这种情况,还是需要注释来说明。

3. Java 中的类似代码

Java 没有 Duck Typing,它只有类似的代码。Java 的 duck typing :

String download(F fetcher){

return fetcher.get("http://xxxx")

}

它同样也用了模板类型。模板 F 必须 extends FetcherInterface ,有了这个限定,就能逼着 download 函数的使用者对 fetcher 实现 get 方法,它解决了需要注释来说明的缺点。

传入的参数必须实现 FetcherInterface 接口,就没有运行时发现错误,编译时发现错误的问题。

但是,它严格上来说不是 Duck Typing 。

如果 download 函数只依赖 fetcher 的 get 方法,而 FetcherInterface 接口必须要实现除 get 方法以外,还有其它方法,那么也要一一实现,非常不灵活。

4. Go 中的 Duck Typing

在 Java 的 Duck Typing 类似代码中,如果 fetcher 参数需要同时实现两个或以上的接口方法时,Java 是没有办法做到的。但 Go 语言可以做到。

type Fetcher interface {

Get(url string) string

}

type Saver interface {

Save(content string)

}

type FetcherAndSaver interface {

Fetcher

Saver

}

func download(f Fetcher) string {

return f.Get("http://xxxx")

}

func save(f saver) {

f.Save("some thing")

}

func downloadAndSave(f FetcherAndSaver) {

content := f.Get("http://xxxx")

f.Save(content)

}

# 实现者

type MyFetcherAndSaver struct {

}

func (f MyFetcherAndSaver) Get(url string) string {

...

}

func (f MyFetcherAndSaver) Save(content string) {

...

}

func main() {

f := MyFetcherAndSaver{}

download(f)

save(f)

downloadAndSave(f)

}

这里定义了三个接口,只要有 Get 方法的就是 Fetcher,只要有 Save 方法的就是 Saver,同时有 Get 方法和 Save 方法就是 FetcherAndSaver 。

实现者 MyFetcherAndSaver 并不需要声明它实现了哪些接口,只要它有相关接口的所定义的方法,那么它的实例,就即能作为 Fetcher 接口来使用,又能作为 Saver 接口来使用,也能作为 FetcherAndSaver 接口来使用。

Go 的实现方法相对比较灵活,又不失类型检查。总的来说,特点有:

即能同时实现多个接口

又具有 python , C++ 的 Duck Typing 灵活性

又具有 java 的类型检查。

duck java_编程语言中的 DUCK TYPING相关推荐

  1. duck typing java_编程语言中的鸭子类型 Duck Typing

    来源 | https://segmentfault.com/a/1190000019607240 1.什么是鸭子类型(duck typing) 百度百科是这样解释的: 这是程序设计中的一种类型推断风格 ...

  2. 编程语言中的 DUCK TYPING|python、c++、java、go

    如果一只动物走起来像鸭子.游泳起来像鸭子.叫起来也像鸭子,那么这只动物就可以被称为鸭子. 许多编程语言都支持 Duck Typing ,通常 Duck Typing 是动态编程语言用来实现多态的一种方 ...

  3. 编程语言中的鸭子类型 Duck Typing

    来源 | https://segmentfault.com/a/1190000019607240 1.什么是鸭子类型(duck typing) 百度百科是这样解释的: 这是程序设计中的一种类型推断风格 ...

  4. 基于对象和面向对象编程范式辨析和主流编程语言中的应用

    基于对象和面向对象编程范式辨析和主流编程语言中的应用 前言 本文的目的是想告诉大家,为什么C++的模板这么强大.为什么Ruby的Duck Typing(像鸭子那样编程)这么强大! 基于对象和面向对象编 ...

  5. 六、Go编程语言中的函数式编程

    @Author:Runsen 任何编程语言都是众所周知的面向对象编程,还有日渐流行的函数式编程,当然Go也不例外,这也是本文的重点..我可以这么说,Go的功力深不深完全就是看函数式编程和面向对象编程. ...

  6. 面向对象编程语言中的接口(Interface)

    在大多面向对象的编程语言中都提供了Interface(接口)的概念.如果你事先学过这个概念,那么在谈到"接口测试"时,会不会想起这个概念来!?本篇文章简单介绍一下面向对象编程语言中 ...

  7. swift语言和python区别_Swift为什么能成为编程语言中的黑马?

    你好,这里是卖桃者说,今天跟你聊一门年轻又很受欢迎的编程语言,Swift. Swift 是苹果于 2014 年在苹果全球开发者大会(WWDC)上发布的编程语言,它可以与 Objective-C 共同运 ...

  8. 盘点key value在各个编程语言中的类型

    个人博客点这里 起步 在编程语言中,有这么一种数据类型,我们经常会使用到,他就是类似于json的键值对类型 那么今天我们就对比一下,在各大编程语言中的key value类型的特点 main pytho ...

  9. 里面怎么定义变量_小哥今天要给朋友们分享一下Java编程语言中的变量与常量的区别...

    喽,各位朋友们大家好! 我是90小哥爱数码,很高兴今天又能和大家在这里见面了. 那么在最近的这段时间里面呢,小哥连续为朋友们介绍了Java计算机编程语言中几个比较重要的知识点.其中包括了Java编程语 ...

最新文章

  1. multiprocessing 多进程
  2. Java 集合类(一)
  3. Subversion(SVN)安装文档
  4. 《LeetCode力扣练习》第155题 最小栈 Java
  5. php header x-auth-token,使用Angular 2正确设置Header X-Auth-Token
  6. 怎样批量调整word 图片大小?
  7. virtualbox display size
  8. cas与java锁_JAVA之锁-cas
  9. Linux驱动中相关函数查询
  10. 极客时间java高级(第二次课程)
  11. 又一个好用的xbox360手柄驱动
  12. Kylin Error:Cannot start job scheduler due to lack of job lock
  13. 铁路警方启用AI眼镜,当场抓逃犯!外媒惊叹不已!
  14. 服务器之间如何实现网络共享
  15. 基于java+ssm+mysql的大学生考勤管理系统及智能分析系统
  16. 50个Java多线程面试题
  17. Web前端开发 icon图标 转 web字体图标
  18. 英读廊——拔了电源插头为什么要等三十秒再重插?
  19. android每天定时打卡,钉钉定时打卡脚本下载|叉叉助手钉钉定时打卡插件安卓版下载 v4.3.1 - 跑跑车安卓网...
  20. c++学编程如何锻炼耐力_我如何学习编程:这是一项耐力运动

热门文章

  1. surface pro java_平板界的楷模!Surface Pro 4简直无敌了
  2. Redhat7.4 同步阿里云镜像rpm包并自建本地yum仓库
  3. 自动驾驶地图中的深度学习
  4. vulhub漏洞复现37_Liferay
  5. findbugs常见错误总结
  6. SQL Server关于AlwaysOn的理解
  7. SQL Server AlwaysON从入门到进阶(6)——分析和部署AlwaysOn Availability Group
  8. 广州二手房价分析与预测
  9. ubuntu 终端显示英文,桌面环境显示中文方法
  10. 比例阀测试仪RT-T101