文档章节

Java 组合与继承

WorldPache
 WorldPache
发布于 2017/05/08 14:01
字数 1198
阅读 6
收藏 0

以前写代码是知道:继承可以帮助我实现类的复用。所以,在需要复用一些代码的时候会很自然的使用类的继承的方式。看书后知道,其实这样做是不对的。长期大量的使用继承会给代码带来很高的维护成本。

面向对象的复用技术

Java代码的复用有继承,组合以及代理三种具体的表现形式。本文将重点介绍继承复用和组合复用。

继承

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

组合

组合(Composition)体现的是整体与部分、拥有的关系,即 has-a 的关系。 网络

组合与继承的区别和联系

在 继承 结构中,父类的内部细节对于子类是可见的。所以我们通常也可以说通过继承的代码复用是一种 白盒式代码复用 。(如果基类的实现发生改变,那么派生类的实现也将随之改变。这样就导致了子类行为的不可预知性;)

组合 是通过对现有的对象进行拼装(组合)产生新的、更复杂的功能。因为在对象之间,各自的内部细节是不可见的,所以我们也说这种方式的代码复用是 黑盒式代码复用 。(因为组合中一般都定义一个类型,所以在编译期根本不知道具体会调用哪个实现类的方法)

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

组合 ,在写代码的时候可以采用面向接口编程。所以,类的组合关系一般在 运行期 确定。

优缺点对比

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

如何选择

相信很多人都知道面向对象中有一个比较重要的原则

『多用组合、少用继承』或者说『组合优于继承』

从前面的介绍已经优缺点对比中也可以看出,组合确实比继承更加灵活,也更有助于代码维护。

所以,

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

注意,并不是说继承就一点用都没有了,前面说的是【在同样可行的情况下】。有一些场景还是需要使用继承的,或者是更适合使用继承。

继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。《 Java编程思想 》

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

本文转载自:http://www.tuicool.com/articles/u2uUZjb

上一篇: java随机
WorldPache
粉丝 0
博文 6
码字总数 834
作品 0
深圳
私信 提问
Java 面试题问与答:编译时与运行时

Q:下面的代码片段中,行A和行B所标识的代码有什么区别呢? public class ConstantFolding { static final int number1 = 5; static final int number2 = 6; static int number3 = 5; stati......

heroShane
2014/02/26
0
0
Java 8 Lambda 表达式:模拟 Mixin 实现类的多重继承

Java 8 开始出现,带来一个全新特性:使用 Lambda 表达式 (JSR-335) 进行函数式编程。今天我们要讨论的是 Lambda 的其中一部分:虚拟扩展方法,也叫做公共辩护(defender)方法。该特性可以让你...

红薯
2012/08/15
6.7K
29
编程思想 之「继承、组合、fianl」

版权声明:Follow your heart and intuition. https://blog.csdn.net/qq_35246620/article/details/78938042 温馨提示:本系列博文(含示例代码)已经同步到 GitHub,地址为「java-skills」,...

维C果糖
2017/12/30
0
0
编程思想 Java中对象的本质

Bruce Eckel 前辈写的《Java编程思想》把问题探讨得非常深入,非常建议同行都学习一下。学习 Java 语言时,老师告诉你 What,自己练习知道 How ,Bruce Eckel 告诉你Why 。 之前已经把后面的...

木云凌
2016/02/23
0
0
依赖、关联、聚合和组合及其之间区别的简单理解

在java以及其他的面向对象设计模式中,类与类之间主要有6种关系,他们分别是:依赖、关联、聚合、组合、继承、实现。他们的耦合度依次增强。 1. 依赖(Dependence) 依赖关系的定义为:对于两...

嘿嘿嘿IT
03/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

程序员随想-关于分享

最早的时候,文字是贵族这些上层人士才会学习的,底层人士没有资格和渠道去学习,同样用文字、图像等其他载体承载的知识大部分也只有贵族阶层才能享受的。后来有了造纸术、印刷术,成本降低,...

Lubby
23分钟前
0
0
聊聊hibernate的session-level repeatable reads

序 本文主要研究一下hibernate的session-level repeatable reads 实例 doInTransaction(session -> { Product product = new Product(); product.setId(1L); product.setQuanti......

go4it
34分钟前
0
0
ubuntu或ubuntu kylin优麒麟中安装QQ、wechat微信、百度网盘

从中国国内的地址下载deepin wine,码云上的。这样网速比较快。然后,按照说明向下安装。 https://gitee.com/wszqkzqk/deepin-wine-for-ubuntu...

gugudu
46分钟前
2
0
基于redis分布式锁实现“秒杀”

最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的demo,阐述实现所谓“秒杀”的基本思路。 业务场景 所谓秒杀,从业务角度看,是短时间内多个用户“争抢”资源...

别打我会飞
今天
14
0
Zookeeper的实践指南

本章重点 1.数据存储2.基于Java API初探Zookeeper的使用3.深入分析Watcher机制的实现原理4.Curator客户端的使用,简单高效 数据存储 事务日志快照日志运行时日志 bin/zookeepe...

须臾之余
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部