【每日学习】鸭子类型


前言

每天学习一点点,别被大家落下太多就行Orz

注:
本篇均为阅读其他博主文章后的摘抄整理,全文无原创。
文章目的是我的学习记录,如您有时间可阅读本文参考文献的原文。
不尽感激。


鸭子类型

一、定义

一个函数不会关心它传入参数的类型,只关心这个参数对应的对象有没有自己想要的方法和属性。如果有,就能运行。如果没有,就不能运行。这就像是我看到了一只鸟,只要它能像鸭子一样叫,像鸭子一样走路,有鸭子一样的白色羽毛,那么,无论它实际上是什么东西,我都认为它是鸭子。

1.1 百度百科定义

这是程序设计中的一种类型推断风格,这种风格适用于动态语言(比如PHP、Python、Ruby、Typescript、Perl、Objective-C、Lua、Julia、JavaScript、Java、Groovy、C#等)和某些静态语言(比如Golang。

一般来说,静态类型语言在编译时便已确定了变量的类型,但是Golang的实现是:在编译时推断变量的类型),支持"鸭子类型"的语言的解释器/编译器将会在解析(Parse)或编译时,推断对象的类型。

1.2 一些其他的解释

其实动态语言是相对静态语言而言的,静态语言的特点是在程序执行前,代码编译时从代码中就可以知道一切,比如变量的类型,方法的返回值类型。

在静态语言中,变量有类型信息,它是一块内存区域,静态语言的优点是代码结构非常规范,便于调试,但有时显得啰嗦。

动态语言中经常提到鸭子类型,所谓鸭子类型就是:如果走起路来像鸭子,叫起来也像鸭子,那么它就是鸭子(If it walks like a duck and quacks like a duck, it must be a duck)。鸭子类型是编程语言中动态类型语言中的一种设计风格,一个对象的特征不是由父类决定,而是通过对象的方法决定的。

我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。

1.3 一个简单的例子

文章代码link如下,希望还是去原博看增加原博点击率:
https://www.cnblogs.com/baxianhua/p/11699068.html

二、优缺点

2.1 优点

优点:
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格

1.允许我们发送未知消息给对象。

2.可以在需要的时候改写其同名方法,只要保证其能响应“method”这个消息。提供动态绑定能力”。(这个如果不理解,请参考项目背景)

2.2 缺点(来自百度百科的批评)

关于鸭子类型常常被引用的一个批评是它要求程序员在任何时候都必须很好地理解他/她正在编写的代码。

本质上,问题是:“如果它走起来像鸭子并且叫起来像鸭子”,它也可以是一只正在模仿鸭子的龙。尽管它们可以模仿鸭子,但也许你不总是想让龙进入池塘。

鸭子类型的提倡者,如吉多·范罗苏姆,认为这个问题可以通过在测试和维护代码库前拥有足够的了解来解决。

总结:需要编写者对程序有足够的了解,而且必须有完善的测试保证代码的正确。

2.3 缺点(来自知乎陌生网友的批评)

接口的方式,可以保证自己的实现是有这个接口的,这是一种强制的契约,要求后来者必须遵循这个契约,在代码上看这是显式的规则;如果是鸭子式的,那么无法保证代码达到一定规模后,后来提交开发代码的,也能够遵循这样的契约,需要遵循的话,就要另外单独起一份文档来说明,在代码上看这是一种隐式的规则。既然一定要遵循这样的规则,那么显式的规则一般情况下要优于隐式的规则。

作者:DamonChen
链接:https://www.zhihu.com/question/20086718/answer/117656234
来源:知乎

三、项目背景

《head first design patterns》 里对“策略模式”一章里,引述了一个故事。

程序员joe因公司业务创建了一个超类Duck,具有方法quack()、swim(),继承自它的各种鸭子都具有这两个方法(行为)。

后来业务变化,需要创建一种会飞的鸭子,joe直接在超类duck上添加方法fly(),导致所有子类鸭子都会飞。

主管觉得不能这样,其他鸭子不能飞。拿小拳拳捶他胸口。

于是joe将fly方法写成一个接口。(java和C#中有接口的概念,是对某些方法的声明,只定义方法但是不提供实现)

会飞的鸭子直接继承Duck和这个fly接口,并自己实现fly行为。

但问题来了,所有需要飞的鸭子都得实现fly方法。而且不同鸭子的同一行为可能不同,比如鸭叫,有的会“呱呱”,有的会“哑哑”。

写成接口的话,随业务扩展,同一接口(行为)可能要写不同版本,维护起来很麻烦。
————————————————
原文链接:https://blog.csdn.net/weixin_36094484/article/details/81504334
这个原文写的真的挺好的,强烈去看。

四、面试题实战

Link:https://cloud.tencent.com/developer/article/1849579(参考文献四)

五、拓展知识

Q:为什么鸭子类型广泛见于Python?
A:因为他的提出者是荷兰程序员吉多·范罗苏姆,他是 Python 程序设计语言的作者(Python之父)。之前在Google工作,一半时间用于维护Python的开发。2022年11月退休后宣布加入微软的DevDiv Team。

Q:Python里的鸭子类型和猴子补丁
A:鸭子类型就是不注重类型,由属性和行为来定义。

猴子补丁是Python中模块和类可以在外部被动态修改这种特性的一个比喻。

为什么叫做猴子补丁呢?在模块和类的外部对模块和类进行修改是一种非常耍赖的做法,会破坏代码的封装结构,这种事情大概只有淘气的猴子喜欢去做,因此形象地称之为猴子补丁。
【参考link3(含代码):https://cloud.tencent.com/developer/article/1484390】

六、参考文献

1.文章的主要参考资料
https://www.cnblogs.com/baxianhua/p/11699068.htmlhttps://www.cnblogs.com/baxianhua/p/11699068.html

2.百度百科
https://baike.baidu.com/item/%E9%B8%AD%E5%AD%90%E7%B1%BB%E5%9E%8B/10845665

3.你知道什么是Python里的鸭子类型和猴子补丁吗?
https://cloud.tencent.com/developer/article/1484390

4.面试扣分点:什么是鸭子类型
https://cloud.tencent.com/developer/article/1849579


总结

不关注类型,关注行为和属性。并能因此调用便被称为鸭子类型。

希望明天能继续学习

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值