Java学习笔记13:复合优先于继承
2014-10-10 22:07
169 查看
继承是实现代码重用的有力手段,但它并非永远是完成这项工作的最佳工具。使用不当会导致软件变得脆弱。在包的内部使用继承是非常安全的,在那里,子类和超类的实现都处在同一个开发人员的控制之下。对于专门为了继承而设计、并且具有很好的文档说明的类说,使用继承也是非常安全的。然而,对普通的具体类,进行跨越包边界的继承,则是非常危险的。
换句话说,子类依赖于其父类中特定功能的实现细节。父类的实现有可能会随着发行版本的不同而有所变化,如果真的发生了变化,子类可能会遭到破坏。这样一来,子类就需要跟随着父类的改变而改变。
有一种方法可以解决继承中的问题:不用扩展现有的类,而是在新的类中增加一个私有域,它引用现有类的一个实例。这种设计就是复合(composition)。
因为现有的类变成了新类的一个组件。新类中的每个实例方法都可以调用被包含的现有类实例中的方法,并返回它的结果。这也叫做转发(forwarding method)。这样的类会非常稳定,它不依赖于现有类的实现细节。
有时候,复合转发的结合也被错误地成为“委托”。从技术的角度来说,这并不是委托,除非包装对象把自身传递给被包装的对象。
只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在“is-a”关系的时候,类B才应该扩展类A。如果你打算让A拓展B,就应该先问一下自己:每一个B确实也是A吗?
我的博客原文:http://www.oak.hk/blog/2014/10/08/favor-composition-over-inheritance/
一、继承打破了封装性
换句话说,子类依赖于其父类中特定功能的实现细节。父类的实现有可能会随着发行版本的不同而有所变化,如果真的发生了变化,子类可能会遭到破坏。这样一来,子类就需要跟随着父类的改变而改变。
二、复合
有一种方法可以解决继承中的问题:不用扩展现有的类,而是在新的类中增加一个私有域,它引用现有类的一个实例。这种设计就是复合(composition)。因为现有的类变成了新类的一个组件。新类中的每个实例方法都可以调用被包含的现有类实例中的方法,并返回它的结果。这也叫做转发(forwarding method)。这样的类会非常稳定,它不依赖于现有类的实现细节。
有时候,复合转发的结合也被错误地成为“委托”。从技术的角度来说,这并不是委托,除非包装对象把自身传递给被包装的对象。
只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在“is-a”关系的时候,类B才应该扩展类A。如果你打算让A拓展B,就应该先问一下自己:每一个B确实也是A吗?
我的博客原文:http://www.oak.hk/blog/2014/10/08/favor-composition-over-inheritance/
相关文章推荐
- Effective Java学习笔记:复合优先于继承
- Java学习笔记---13.面向对象编程08-Java中继承的概念,子类实例化过程,super()及方法复写
- Java 学习笔记 (13) - 基本内存分析 和 垃圾回收机制
- 传智博客学习笔记13--JAVA GUI
- Java学习笔记13:输出26个字母矩阵
- java学习笔记13——多媒体技术
- C\C++ 程序员从零开始学习Android - 个人学习笔记(八) - java基础 - 继承、抽象类、接口、内部类(待续)
- Java构造函数的继承-Java 学习笔记 (14)
- java 设计模式学习笔记(13) - 适配器模式
- java学习笔记七——继承
- 18天Java学习---13.面向对象编程08-Java中继承的概念,子类实例化过程,super()及方法复写
- Java与Flex学习笔记(13)----Flex中解析地址栏传递的参数
- Effective Java 学习笔记(13)
- java学习笔记(二十二)继承的进一步研究
- JAVA学习笔记之七继承和多态
- Java学习笔记18天---(13)
- thinking in java 学习笔记(一) 接口于多重继承
- 学习Java.对于继承和多态的随堂笔记
- 黑马程序员学习笔记四——Java 面向对象 特点之 继承
- C\C++ 程序员从零开始学习Android - 个人学习笔记(八) - java基础 - 继承、抽象类、接口、内部类(待续)