💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## [使用继承设计](https://lingcoder.gitee.io/onjava8/#/book/09-Polymorphism?id=%e4%bd%bf%e7%94%a8%e7%bb%a7%e6%89%bf%e8%ae%be%e8%ae%a1) 学习过多态之后,一切看似都可以被继承,因为多态是如此巧妙的工具。这会给设计带来负担。事实上,如果利用已有类创建新类首先选择继承的话,事情会变得莫名的复杂。 更好的方法是首先选择组合,特别是不知道该使用哪种方法时。组合不会强制设计是继承层次结构,而且组合更加灵活,因为可以动态地选择类型(因而选择相应的行为),而继承要求必须在编译时知道确切类型。下面例子说明了这点: ~~~ // polymorphism/Transmogrify.java // Dynamically changing the behavior of an object // via composition (the "State" design pattern) class Actor { public void act() {} } class HappyActor extends Actor { @Override public void act() { System.out.println("HappyActor"); } } class SadActor extends Actor { @Override 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**引用,该引用被初始化为指向一个**HappyActor**对象,这意味着`performPlay()`会产生一个特殊行为。但是既然引用可以在运行时与其他不同的对象绑定,那么它就可以被替换成对**SadActor**的引用,`performPlay()`的行为随之改变。这样你就获得了运行时的动态灵活性(这被称为状态模式)。与之相反,我们不能在运行时决定继承不同的对象,那在编译时就完全确定下来了。 有一条通用准则:使用继承表达行为的差异,使用属性表达状态的变化。在上个例子中,两者都用到了。通过继承得到的两个不同类在`act()`方法中表达了不同的行为,**Stage**通过组合使自己的状态发生变化。这里状态的改变产生了行为的改变。