前言
学习了多态之后,看起来似乎所有东西都可以被继承,因为多态是一种如此巧妙的工具。事实上,当我们用现成的类来建立新类时,如果首先考虑使用继承技术,反倒会加重我们的设计负担,使事情变得不必要地复杂起来。
更好的方法是首先选择“组合”,尤其是不能十分确定应该使用哪一种方式时。组合不会强制我们的程序设计进入继承的层次结构中。而且,组合更加灵活,因为它可以动态选择类型(因此也就选择了行为);相反,继承在编译时就需要知道确切类型。下面举例说明这一点:
示例源码
package com.mufeng.theeighthchapter; class Actor { public void act() { } } class HappyActor extends Actor { public void act() { System.out.println("HappyActor"); } } class SadActor extends Actor { public void act() { System.out.println("SadActor"); } } class Stage { private Actor actor = new HappyActor(); public void change() { actor = new SadActor(); } public void performPlay() { actor.act(); } } public class Transmogrify { public static void main(String[] args) { Stage stage = new Stage(); stage.performPlay(); stage.change(); stage.performPlay(); } }
输出结果
HappyActor SadActor
源码解析
在这里,Stage对象包含一个对Actor的引用,而Actor被初始化为HappyActor对象。这意味着performPlay()会产生某种特殊行为。既然引用在运行时可以与另一个不同的对象重新绑定起来,所以SadActor对象的引用可以在actor中被替代,然后由performPlay()产生的行为也随之改变。这样一来,我们在运行期间获得了动态灵活性(这也称作状态模式)。与此相反,我们不能在运行期间决定继承不同的对象,因为它要求在编译期间完全确定下来。
一条通用的准则是:“用继承表达行为间的差异,并用字段表达状态上的变化”。在上述例子中,两者都用到了:通过继承得到了两个不同的类,用于表达act()方法的差异:而Stage通过运用组合使自己的状态发生了变化。在这种情况下,这种状态的改变也就产生了行为的改变。
时间: 2024-12-19 00:24:37