来源 | https://segmentfault.com/a/1190000019607240

1、什么是鸭子类型(duck typing)

百度百科是这样解释的:

这是程序设计中的一种类型推断风格,这种风格适用于动态语言(比如PHP、Python、Ruby、Typescript、Perl、Objective-C、Lua、Julia、JavaScript、Java、Groovy、C#等)和某些静态语言(比如Golang,一般来说,静态类型语言在编译时便已确定了变量的类型,但是Golang的实现是:在编译时推断变量的类型),支持"鸭子类型"的语言的解释器/编译器将会在解析(Parse)或编译时,推断对象的类型。

有没有感觉很难理解?下面我们就来用通俗的语言介绍一下鸭子类型(Duck Typing)。

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

许多编程语言都支持 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 typing java_编程语言中的鸭子类型 Duck Typing相关推荐

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

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

  2. [转]编程语言中的 鸭子模型(duck typing)

    在学习Python的时候发现了鸭子类型这个术语,听起来好像很有意思一样,所以把它记下来. 鸭子类型的核心概念在于一个对象的有效语义,不是继承自特定的类或者实现特定的方法,而是 由当前的属性和方法集合决 ...

  3. duck typing java_到底啥是鸭子类型(duck typing)带简单例子

    #百度百科鸭子类型定义 这是程序设计中的一种类型推断风格,这种风格适用于动态语言(比如PHP.Python.Ruby.Typescript.Perl.Objective-C.Lua.Julia.Jav ...

  4. 【Python】浅谈 鸭子类型 (Duck Typing)

    目录 一.来源 二.说明 三.举例 四.不足 一.来源 在程序设计中,鸭子类型 (duck typing) 是动态类型的一种风格.在此风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口, ...

  5. python中的鸭子类型

    浅层理解 走路像鸭子,说话像鸭子,它就是鸭子 深层理解 指的是面向对中,子类不需要显示的继承某个类,只要有某个的方法和属性,那我就属于这个类 编程语言中的鸭子类型说明 假设有个鸭子类Duck类,有两个 ...

  6. Python笔记 · 鸭子类型 / Duck Typing

    1. 问题的由来 我初次意识到鸭子类型的存在是在学习Sklearn时,在<Hands-On Machine Learing>一书的第二章,作者提供了一个自定义的Tansformer,使用自 ...

  7. Python编程基础:第四十九节 鸭子类型Duck Typing

    第四十九节 鸭子类型Duck Typing 前言 实践 前言 本节我们一起学习一个非常有趣的知识点:鸭子类型.有这么一句话:If it walks like a duck, and it quacks ...

  8. 鸭子类型duck typing(动态)

    在程序设计中,鸭子类型(duck typing)是动态类型的一种风格.在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定.这个概念的名字来源于由Ja ...

  9. Python 语言中的 “鸭子类型”

    Python 语言中的 "鸭子类型" 继承 多态 鸭子类型 不要检查它是不是鸭子.它的叫声像不像鸭子.它的走路姿势像不像鸭子,等等.具体检查什么取决于你想使用语言的哪些行为.(co ...

最新文章

  1. 开启Apache mod_rewrite模块(解决404 Not Found)
  2. 前缀和与差分的使用(新手快速入门)
  3. ASP.NET MVC增删改查
  4. Android判断界面
  5. tensorflow实现反卷积
  6. Button 自动换行
  7. XP下使用submit text3遭遇死机强制重启导致以及代码数据丢失(无法读取源文件或磁盘)
  8. linux下连接mysql数据库命令,linux连接mysql命令
  9. MySQL参数max_connect_errors分析释疑
  10. elasticsearch-head离线安装
  11. 设置透明主题引起动画失效以及打开其他应用闪现桌面图标的问题
  12. 运维黄金4指标,构筑
  13. 虚拟机安装教程(多图)
  14. 智能客服vs人工客服,两者真水火不容?
  15. GO运行时报错: cannot find package “.“ in:
  16. 洛谷P3975 - [TJOI2015]弦论
  17. 水哥:用好泳道图,轻松化解复杂系统的业务流程梳理 | 真北敏捷群分享
  18. 金庸不朽,将在区块链世界中永生
  19. 如何把Iconfont阿里巴巴矢量图标库引入web项目和微信小程序中,拿走不谢
  20. [通信技术资料]基于STC89C52的韦根数据接收

热门文章

  1. Blog_Backup:绿色博客备份工具
  2. Fail2ban初识
  3. BFS Codeforces Round #297 (Div. 2) D. Arthur and Walls
  4. urllib2打开URL(含中文)的问题
  5. WPF中读取txt文件并让其在RichTextBox中显示
  6. DataSet case sensitive issue
  7. 手机html检测蓝牙打印机,打印机手机确认.html
  8. 【ABAP】供应商进项税额查询报表开发
  9. Field-Symbols总结
  10. 凭证 90000000 保存(帐户确定出错)