为什么阿里巴巴建议开发者谨慎使用继承?

从学习Java的第一天起,我们就知道Java是一种面向对象语言,而学习Java的第二天,我们就知道了面向对象的三大基本特性是:封装、继承、多态。

所以,对于很多开发者来说,继承肯定都是不陌生的。但是,继承一定适合所有的场景吗?毫无忌讳的使用继承来做代码扩展真的好吗?

为什么《阿里巴巴Java开发手册》中有一条规定:谨慎使用继承的方式进行扩展,优先使用组合的方式实现。

本文就来针对这些问题,简单分析一下。

1

面向对象的复用技术

每个人在刚刚学习继承的时候都会或多或少的有这样一个印象:继承可以帮助我实现类的复用。

所以,很多开发人员在需要复用一些代码的时候会很自然的使用类的继承的方式,因为书上就是这么写的(老师就是这么教的)。但是,其实这样做是不对的。长期大量的使用继承会给代码带来很高的维护成本。

前面提到复用,这里就简单介绍一下面向对象的复用技术。复用性是面向对象技术带来的很棒的潜在好处之一。如果运用的好的话可以帮助我们节省很多开发时间,提升开发效率。但是,如果被滥用那么就可能产生很多难以维护的代码。

作为一门面向对象开发的语言,代码复用是Java引人注意的功能之一。Java代码的复用有继承,组合以及代理三种具体的表现形式。

2

继承

继承(Inheritance)是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系。

继承是一种is-a关系。如苹果是水果,狗是动物,哈士奇是狗。

3

组合

组合(Composition)体现的是整体与部分、拥有的关系。

组合是一种has-a的关系。如汽车有一个发动机,学校有一个老师等。

4

组合与继承的区别

首先,从类的关系确定时间点上,组合和继承是有区别的:

继承,在写代码的时候就要指明具体继承哪个类,所以,类的继承关系是在编译期就确定的。并且从基类继承来的实现是无法在运行期动态改变的,因此降低了应用的灵活性。

组合,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在运行期确定。另外,代码复用方式上也有一定区别:

继承结构中,父类的内部细节对于子类是可见的。所以我们通常也可以说通过继承的代码复用是一种白盒式代码复用。

如果基类的实现发生改变,那么派生类的实现也将随之改变。这样就导致了子类行为的不可预知性。

组合是通过对现有的对象进行拼装(组合)产生新的、更复杂的功能。因为在对象之间,各自的内部细节是不可见的,所以我们也说通过组合的代码复用是黑盒式代码复用。

因为组合中一般都定义一个类型,所以在编译期根本不知道具体会调用哪个实现类的方法。

最后,Java中不支持多继承,而组合是没有限制的。就像一个人只能有一个父亲,但是他可以有很很多辆车。

5

优缺点对比

组合关系继承关系
优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性
优点:具有较好的可扩展性缺点:支持扩展,但是往往以增加系统结构的复杂度为代价
优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象缺点:不支持动态继承。在运行时,子类无法选择不同的父类
优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口缺点:子类不能改变父类的接口
缺点:整体类不能自动获得和局部类同样的接口优点:子类能自动继承父类的接口
缺点:创建整体类的对象时,需要创建所有局部类的对象优点:创建子类的对象时,无须创建父类的对象

6

为什么组合优于继承

相信很多人都知道面向对象中有一个比较重要的原则『多用组合、少用继承』或者说『组合优于继承』。

从前面的介绍已经优缺点对比中也可以看出,组合比继承更加灵活,也更有助于代码维护。其具有不破坏封装性、具有更好的可扩展性、支持动态组合、整体类可以改变局部类的行为等优点。

所以,建议在同样可行的情况下,优先使用组合而不是继承。因为组合更安全,更简单,更灵活,更高效。

注意,并不是说继承就一点用都没有了,前面说的是【在同样可行的情况下】。

有一些场景还是需要使用继承的,或者是更适合使用继承。另外,除了《阿里巴巴Java开发手册》,在很多其他资料中也有关于组合和继承的介绍和使用约束:

继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。

一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。《Java编程思想》

只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在is-a关系的时候,类B才应该继续类A。《Effective Java》

Image placeholder
Lvge
未设置
  67人点赞

没有讨论,发表一下自己的看法吧

推荐文章
阿里巴巴为什么能抗住90秒100亿?看完这篇你就明白了!

1、概述本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则。2、

替换Oracle,从阿里巴巴到亚马逊-他们在逃离什么?

AWS终于在2020年前兑现了自己的承诺:彻底替换Oracle数据库。这几乎是每年OracleOpenworld大会上LarryEllision固定的一个梗,他说亚马逊 在号召用户迁移使用AWS的数据

阿里巴巴重磅发布含光 800 芯片:顶 10 个 GPU

2019年9月25日,2019杭州·云栖大会在云栖小镇举行。回顾历届大会,每年都有那么几件大事情值得关注,比如提出“DT时代”、“五新”概念,宣布建设“城市大脑”,成立达摩院、半导体公司“平头哥”等

干货 | 阿里巴巴HBase高可用8年抗战回忆录

前言2011年毕玄和竹庄两位大神将HBase引入阿里技术体系,2014年接力棒转到东8区第一位HBasecommiter天梧手中,多年来与淘宝、旺旺、菜鸟、支付宝、高德、大文娱、阿里妈妈等几乎全BU合

超大规模商用 K8s 场景下,阿里巴巴如何动态解决容器资源的按需分配问题?

导读:资源利用率一直是很多平台管理和研发人员关心的话题。本文作者通过阿里巴巴容器平台团队在这一领域的工作实践,整理出了一套资源利用提升的方案,希望能够带给大家带来一些讨论和思考。引言不知道大家有没有过

阿里巴巴架构师:十问业务中台和我的答案

Photo@  ZachLucero文 |王思轩一切业务数据化,一切数据业务化。“中台”概念这几年非常火,特别是阿里、腾讯、百度、京东等互联网公司最近频繁的基于中台调整组织架构,把“中台”的热度又上升

阿里巴巴向全社会开放黑科技:“泡在水里”的服务器

为了让数据中心更绿色,阿里工程曾将服务器“泡在水里”进行散热,节能超70%,今天这项黑科技的神秘面纱被揭开。2020年1月6日,阿里巴巴宣布将“浸没式液冷数据中心技术规范”向全社会开放。这项规范旨在用

开发者为什么不愿意参与开源贡献?不仅是钱的原因

  对企业和开发人员来说,开源贡献具有重要意义。它能帮助企业建立自己的开源标准,同时能够吸引多样化人才,可以帮助开发人员丰富开发经验,提升个人能力。但事实上,如此明显的优势并没有吸引更多的开发人员从事

为什么不建议在 MySQL 中使用 UTF-8?

最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的MariaDB中保存一个UTF-8字符串,然后出现了一个离奇的错误:Incorrect string value: ‘😃 

一文告诉你全世界最顶级的开发者都在使用什么数据库

作为一名IT行业从业者,其实从去年已经隐隐约约感觉到数据库的有变化,只是没有想到变得这么快。今年的一些事情实实在在地给了某些数据库重击,如果以前去某数据库还是喊喊,然后该用还用,今年从传统领域刮起的去

大会资料下载|热门技术风口下开发者应该关注些什么?

4月16日,OracleCode2019开发者大会在深圳圆满落幕。今年的大会有将近1000名开发者齐聚现场,45万码农同时在线观看直播。现场,来自国内外的技术专家,围绕云计算、自治数据库、IoT、区块

PHP构造函数的继承问题

PHP构造函数的继承问题 关于类继承,总有一个常见的问题,这就是构造函数的使用。子类实例化时会执行父类的构造函数吗?如果是这样,倘若子类也有自己的构造函数会怎么样?子类构造函数在父类构造函数之后执行,

css有不可继承属性吗?

css继承性:CSS继承可定义为特定的css属性向下传递到子孙元素,就是指被包在内部的标签将拥有外部标签的样式,即子元素可以继承父元素的属性。继承是一种规则,它允许样式不仅应用于某个特定html标签元

前端培训-中级阶段(31)- Class 的基本语法、Class 的继承(2019-12-26期)

前端最基础的就是HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知

阿里云为什么有底气喊出“全面上云的拐点到了”?

摘要:拐点,又称反曲点,在高等数学里,拐点指的是凹凸性变化的点,在生活中借指趋势发生变化的点。(例如:经济运行出现回升拐点)虽然上云是大势所趋,但企业全面上云可能还需要一些时日,这或许是绝大部分从业者

硬核盘点,华为面向开发者的十大技术

随着社会的发展,科技的进步,5G落地、AI爆发、大数据持续突破、云计算已然成为新时代的水电煤。日益增多的新兴技术,为开发者带来机遇的同时也带来了不少挑战。尽管开发者们经常身处历史性事件的前沿,但由于

喊话 JavaScript 开发者:玩 DOM 也要专业范儿

别再害怕DOM了,让我们充分挖掘DOM的潜力,你会真的爱上它。 2008年,当我刚成为一名专业Web开发人员参加工作时,我了解一些HTML、CSS和PHP的知识。那时我也在学习JavaScript

程序员常用的15 种开发者工具推荐

  程序员常用的15种开发者工具引荐:Java线上诊断工具Arthas、IDE插件CloudToolkit、混沌实验注入工具ChaosBlade、Java代码规约扫描插件、应用实时监控工具ARMS、静

初级,中级,高级开发者间的区别

初级,中级,高级开发人员不能仅仅通过开发年限来界定,可能存在初级开发人员比一个高级开发人员年龄大的现实。这时候只能依靠掌握的技能来做区分这三者。当然,这并不代表高级开发人员精于一切,但是,的确高级开

Eclipse发布:2019年物联网开发者调查

如果你想了解一项重要技术的未来,那么先看开发人员在做什么。考虑到这一点,在EclipseFoundation对 1700 多名物 联 网开 发 人 员 (pdf) 进行的一项新调查中,可以获得对整个物

持续可用与CAP理论 – 一个数据库系统开发者的观点

本文作者为蚂蚁金服OceanBase研究员日照,发表于2015年。持续可用本文主要针对金融数据库,认为金融数据库的持续可用包含两点:一个是强一致性;另外一个是高可用性。数据库系统必须是强一致性的系统,

指引趋势与方向!2019开发者调查报告出炉

近日国外开发者平台HankerRank发布了2019年开发者技能调查报告,该报告根据对71,281位开发者的调查得出。作者从中选取了一部分,给大家解读一下。12018年最受欢迎的开发语言经过调查,2

从十万份开发者调查报告中,发现了这些信息

StackOverflow是一个面向程序员的技术问答网站,每年都会进行一次开发者问卷调查。本次收集了10万名开发者的调查问卷,分别对程序员的工作状况、开发语言、工具以及生活习惯等做了调查。参与调查的开

爽到飞起!微软命令行工具发布!引诱开发者叛逃Mac,开源六小时冲上GitHub第二

晓查栗子乾明发自凹非寺转自量子位 |公众号QbitAIWoW!Awesome!MyGod!这是不少抱着Mac参加微软Build大会的开发者,看到命令行工具WindowsTerminal后的第一反应。随