我为什么讨厌继承?
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
面向对象三要素封装、继承、多态。我上大学学习 Java 的时候,很多相关书籍都会讲解这三要素,以现在的我看来,封装和多态是必要的。 但是继承... 继承有什么问题在我刚参加工作的第三年,我参与到了中国移动和地图 App 的开发工作中,当时我负责改造该 App 的核心网络请求模块。 那个时候还没有流行使用 OkHttp ,更没有 Retrofit 这种优秀的网络开源库,整体还是使用原始的 HttpConnection 去完成网络请求,自己封装里面的实现逻辑。 我当时理解完需求之后,整理了网络库需要满足的功能,大概如下:
自然而然,我想到了这种方案,
一开始,这样做非常方便,例如:如果一个请求只需要获取文本内容,那么就直接继承 也就是说,一个请求需要实现哪些能力,那么就继承那个基类就好了。
而使用这个网络库的人,只需要按照 API 文档中的 API 名称,用这个请求就行了,例如 但是后续改动,让我越来越 Hold 不住这种继承链了:有的 API 需要鉴权,有的不需要;部分 API 会有不同的 Header;有的 API 返回结果加密方式和之前的不一样。 慢慢的,我发现我的继承链越来越长,为了让我的 API 使用保持简洁,甚至出现了类似菱形继承的情况(这里不是说 Java 可以菱形继承):
实际上 后面这种问题越来越多,虽然同事们用起来非常方便(对照文档直接 为什么会这样呢? 一句话总结“继承”这个特性,本来想干三件事,结果三件事互相打架,最后搞得谁都不开心。 好的,我来换个思路解释,以 Java 这种语言为例: 比如你写一个 听起来很美好,对吧?(当时我就是这么认为的) 但问题来了——我们其实用“继承”做了三件完全不同的事,而这三件事根本不是一回事! 第一件事:分类 —— 这东西属于哪一类比如:“正方形是一种矩形”,“狗是一种动物”。 这是从现实世界逻辑出发的,叫“本体论”(别被名字吓到,就是“分类”的意思)。 这合理啊,正方形确实是矩形的一种特殊情况。 第二件事: 能替换吗 —— 程序能不能当同一种东西用比如:如果一个函数要求传入一个 如果可以,就叫“可替换”,这是程序正确性的问题。 但现实中不行!因为矩形可以改宽高,而正方形一改宽高就不是正方形了。 所以:虽然“正方形是矩形”在数学上成立,但在代码里不能随便替换!
第三件事: 省代码 —— 别重复写一样的代码比如: 这纯粹是为了偷懒/复用代码,跟“是不是动物”没关系。 好处:少写代码。 风险:万一以后某个“动物”不吃东西(比如机器人宠物),你就得硬改,或者搞一个新的继承链,破坏设计。 问题来了Java 只给了你一个“继承”关键字,却让你同时干这三件事。 结果:
三件事混在一起,必然出问题! 就像公司里面的团队,虽然大家都属于同一个组,但是如果目标不一致,这必然导致开发问题! 那怎么办这是我后来,才学到的知识。 别用“继承”干所有事!分开处理:
还记得那句经典的建议吗:“优先使用组合,而不是继承。 ” 来,举个例子,假设你要做“交通工具”系统:
总结“继承”就像一把瑞士军刀,本来想切菜、开瓶、剪线都行,结果发现:切菜时刀片会弹出来割手,开瓶时螺丝刀又碍事。 所以聪明人怎么做? 切菜用菜刀,开瓶用开瓶器,剪线用剪刀。各干各的,互不干扰。 编程也一样: 别指望“继承”解决所有问题,该用接口用接口,该用组合用组合。 这样,代码才清爽,bug 才少,而你,我的朋友,才睡得着觉! 转自https://juejin.cn/post/7601384029611425807 该文章在 2026/2/4 16:24:42 编辑过 |
关键字查询
相关文章
正在查询... |