软件设计之美
郑晔
开源项目 Moco 作者
19890 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 42 讲
软件设计之美
15
15
1.0x
00:00/00:00
登录|注册

16 | 面向对象之多态:为什么“稀疏平常”的多态,是软件设计的大杀器?

你好!我是郑晔。
前面两讲,我们讲了面向对象的两个特点:封装和继承,但真正让面向对象华丽蜕变的是它的第三个特点:多态。
有一次,我在一个 C++ 的开发团队里做了一个小调查。问题很简单:你用过 virtual 吗?下面坐着几十个 C++ 程序员,只有寥寥数人举起了手。
在 C++ 里,virtual 表示这个函数是在父类中声明的,然后在子类中改写(Override)过。或许你已经发现了,这不就是多态吗?没错,这就是多态。这个调查说明了一件事,很多程序员虽然在用支持面向对象的程序设计语言,但根本没有用过多态。
只使用封装和继承的编程方式,我们称之为基于对象(Object Based)编程,而只有把多态加进来,才能称之为面向对象(Object Oriented)编程。也就是说,多态是一个分水岭,将基于对象与面向对象区分开来,可以说,没写过多态的代码,就是没写过面向对象的代码。
对于面向对象而言,多态至关重要,正是因为多态的存在,软件设计才有了更大的弹性,能够更好地适应未来的变化。我们说,软件设计是一门关注长期变化的学问,只有当你开始理解了多态,你才真正踏入应对长期变化的大门。这一讲,我们就谈谈多态。

理解多态

多态(Polymorphism),顾名思义,一个接口,多种形态。同样是一个绘图(draw)的方法,如果以正方形调用,则绘制出一个正方形;如果以圆形调用,则画出的是圆形:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

面向对象编程中的多态是软件设计的重要特点,它使得一个接口可以有多种不同的实现形态。多态的实现需要构建抽象,即找出不同事物的共同点,然后以接口的方式体现出来。接口将变的部分和不变的部分隔离开来,有助于应对系统变化。理解多态需要理解接口的价值,而面向接口编程的价值根植于多态。多态对程序员的要求更高,需要有长远的眼光,看到未来的变化。在面向对象程序设计语言中,多态的实现下沉到了运行时,通过虚拟函数表的查表过程来实现,从而限制了函数指针的使用,提高了程序行为的可预期性。多态的存在使得软件设计具有更大的弹性,能够更好地适应未来的变化,因此对于软件设计而言,多态是一种大杀器。 文章还介绍了多态不一定要依赖于继承实现,而更重要的是封装和多态。此外,文章还提到了面向对象编程的三个特点:封装、继承和多态,以及面向对象的设计原则。作者鼓励读者了解Go语言或Rust语言是如何支持多态,以拓展读者的知识面。 总的来说,本文深入探讨了面向对象编程中的多态特点,强调了多态的重要性和灵活性,对于想深入了解软件设计和面向对象编程的读者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《软件设计之美》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • sam
    自己理解总结:多态就是接口一样,实现不同。其前提是构建抽象,找出事物的共同点。让程序员更着眼未来的变化。

    作者回复: 这个理解很对。

    2020-07-01
    15
  • Being
    这几讲下来终于体会到多学几门语言的妙处了。对于Java和C++,总是有用树形关系在考虑多态(大概就是继承引导的思维吧),下来看了Go和Rust对于多态的支持,虽然理解不深,但给我的初步印象就是通过组合接口来实现多态。 建立起抽象确实不是件一蹴而就的事情,往往伴随着在某一领域下,对需求认识和理解的不断加深。

    作者回复: 日拱一卒,体会设计之美。

    2020-07-02
    12
  • 蓝士钦
    某系统需要对普通用户增删改查,后来加了超级管理员用户也需要增删改查。把用户的操作抽象成接口方法,让普通用户和管理员用户实现接口方法…… 那么问题来了,这些接口方法的出入参没法完全共用,比如查询用户信息接口,普通用户和超级管理员用户的返回体信息字段不同。所以没法抽象,请问一下老师这种应不应该抽象呢?如果应该做成抽象需要怎么分离变的部分呢

    作者回复: 应该分,因为管理员和普通用户的关注点是不同的。管理员和普通用户可以分别提供接口,分别提供相应的内容。 如果说非要二者共用,可以考虑在服务层共用,在接口层面分开,在接口层去适配不同的接口。

    2020-07-01
    2
    10
  • Jxin
    go就是文中所述的 Duck Typing。只是用来写算法题和小玩意。不是很注意。 Duck Typing的话,能通过ide便捷的找到所有实现吗?这是个问题。

    作者回复: 与工具结合起来的时候,太灵活的动态语言,优势就不那么明显了。

    2020-07-01
    3
    4
  • 佟宏元
    想要具备多态的思想,首先要有抽象的意识,有发现变与不变的敏锐。能否抽象出变与不变的点,却是需要对自己的实际业务有深入的理解,这就要求不能是普通的码农,需要具备业务设计的能力。

    作者回复: 这里所谓的“普通”,实际上是一种无知,不知道一个程序员完整的知识面应该是什么样子。

    2020-11-21
    3
  • 桃源小盼
    react可以说是,大多数情况下基于组件编程吗?

    作者回复: React 是基于组件编程的。

    2020-07-01
    3
  • 倡印
    有些语言中提供的委托,其实也可以理解成是一种多态

    作者回复: 可以这么理解。

    2020-09-07
    2
    2
  • 呆呆狗的兽
    前端时间学了TypeScript,他的多态就像文中展示的一样,只要一个对象与interface有同样的方法定义,那么就可以当做参数传入,一开始学的时候,感觉这样做会不会代码很难写或者会发生什么意想不到的问题,但写了写发现是我多虑了,感觉各语言都有各自的做法,让一些原本在其他语言习惯了的特性在当前语言上即使特性展现方式不同,也能很正常且好用

    作者回复: 语言的发展都是因为要做越来越复杂的事情,需要提供各种强有力的支撑。

    2021-06-25
    1
  • KevinSu
    List<> list= new ArrayList<String>;我对这个例子有点疑惑的点,假如我需要使用ArrayList里特有的方法但List没有暴露的方法呢,这是不是就只能声明ArrayList了

    作者回复: 是的,那个时候你已经确实需要ArrayList了

    2021-06-02
    2
  • 阳仔
    使用多态,首先要构建抽象,而抽象就是从不同的对象中找出共同的部分,根本就是要注意分离关注点 然后将抽象出部分使用接口表现出来, 所以封装和多态是面向对象最重要的原则 在实际工作上我们的APP因为需要支持各种设备和硬件负载,每个设备和负载的数据和UI界面也有可能是不大一样的交互 随着业务的发展,需要在一个APP中适配和兼容,这给开发和测试带来极大的不便 我的一个想法是利用利用封装将不同设备和负载抽象相同出相同的部分,将不同的部分使用接口分离出来 不知道大佬有没有更好的想法,可以参考?
    2020-07-01
    1
    2
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部