OOP三大特性最重要的:多态。
很多程序员虽然在用支持OOP的语言,但却从未用过多态。
- 只使用封装、继承的编程方式,称为基于对象(Object Based)编程
- 只有加入多态,才能称为OOP
没写过多态,就是没写过OO代码。
正是有了多态,软件设计才有更大弹性,更好拥抱变化。
如何理解多态h1>
多态,即一个接口,多种形态。
一个draw方法,以正方形调用,则画正方形;以圆形调用,则画圆形:
既然多态这么好,为什么很多人感觉无法在项目中自如地多态p>
多态需构建抽象。
构建抽象
找出不同事物的共同点,这是最具挑战的。令人懵逼的也往往是眼中的不同之处。在很多人眼里,鸡就是鸡,鸭就是鸭。
寻找共同点,根基还是分离关注点。
当你能看出鸡、鸭都有羽毛,都养在家里,你才可能识别“家禽”。
接口的意义
接口隔离了变化部分、不变部分
- 不变部分
接口的约定 - 变化部分
子类各自的实现
最影响程序的就是各种变化。有时需求来了,你的代码就得跟着改,一个可能的原因就是各种代码混在了一起。
比如,一个通信协议的调整,你要改业务逻辑,这明显不合理。
所以识别出变化与不变,是区分程序员水平的一大标准。
接口是边界
清晰界定系统内不同模块的职责很关键,而模块间彼此通信最重要的就是通信协议,对应到代码中的接口。
很多程序员在接口中添加方法很随意,因为他们眼里,不存在实现者和使用者的角色差异,导致没有清晰边界,后果就是模块定义随意,彼此之间互相耦合,最终玩死自己。
所以,理解多态在于理解接口,理解接口在于谨慎选择接口中的方法。
面向接口编程的价值就源于多态。
这些原则你可能都听说过,但写代码时,就会忽略细节。
比如:
多态对程序员的要求更高,需要你能感知未来变化!
实现多态
OOP会限制使用函数指针,它是对程序控制权的间接转移施加了约束。
理解这句话,就要理解多态如何实现的。
Linux文件系统用C实现了OOP,就是用了函数指针:
C++这种注重运行时消耗的语言:
- 只有virtual函数会出现在虚拟函数表
- 普通函数就是直接的函数调用,以此减少消耗
对于Java程序员,可通过给无需改写的方法添加final帮助运行时优化。
当多态成为语法,就限制了函数指针的使用,犯错率大大降低!
没有继承的多态
封装,多态。至于继承,却不是必然选项。只要能够遵循相同接口,即可表现出多态,所以,多态并不一定要依赖继承。
动态语言中一个常见说法 – Duck Typing,若走起来像鸭子,叫起来像鸭子,那它就是鸭子。
两个类可不在同一继承体系下,但只要有相同接口,就是一种多态。
如下代码段:Duck和FakeDuck不在一棵继承树上,但make_quack调用时,它们俩都可传进去。
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!