李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
用继承进行设计
Leefs
2019-10-16 AM
1345℃
0条
# 用继承进行设计 ### 前言 在我们学习多态的过程中会有这样一种体会,看起来似乎所有的东西都可以被继承。 事实上,当我们用现成的类来建立新类时,如果首先考虑使用继承技术,反倒会加重我们的设计负担,使事情变得不必要地复杂起来。 **那我们对程序进行设计时应该选择哪种技术呐?** 答案是:首先选择“**组合**”。 尤其是不能十分确定应该使用哪一种方式时。组合不会强制我们的程序设计进入继承的层次结构中。而且,组合更加灵活,因为它可以**动态选择类型**(因此也就选择了行为);相反,继承在编译时就需要知道确切类型。 *注:本篇先不详细阐述继承和组合的关系,在后面的文章中将进行详细讲解* ### 代码示例 ```java package ThinkInJava; 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(); } } ``` 运行结果: ```java HappyActor SadActor ``` (本例来自 Thinking in Java p165 ) **代码执行过程:** 1. 1.创建**Stage**对象 2. 2.执行方法**private Actor actor = new HappyActor();** + 创建HappyActor对象并进行向上转型 + 初始化Actor类 3. 3.执行**stage.performPlay();** + 执行actor.act();此时调用的是HappyActor类的act()方法 + 打印输出HappyActor 4. 4.执行**stage.change();** + 创建SadActor对象并进行向上转型因为和HappyActor类的父类相同 + 初始化Actor类 5. 5.执行**stage.performPlay();** + 执行actor.act();此时调用的是SadActor类的act()方法 + 打印输出SadActor **代码解析:** 1. 1.SadActor继承了Actor覆写了Actor中的act()方法 2. 2.HappyActor继承了Actor覆写了Actor中的act()方法 3. 3.Stage是使用组合对SadActor和HappyActor进行对象创建 **关键代码分析:** + stage.change();将之前创建HappyActor对象转换成了对SadActor对象的创建,达到了**动态选择类型**的效果。 在这里,**Stage**对象包含一个对**Actor**的引用,而**Actor**被初始化为**HappyActor**对象。这意味着**performPlay()**会产生某种特殊行为。既然引用在运行时可以与另一个不同的对象重新绑定起来,所以**SadActor**对象的引用可以在**actor**中被替代,然后由**performPlay()**产生的行为也随之改变。这样一来,我们在运行期间获得了动态灵活性(这也称作状态模式)。与此相反,我们不能在运行期间决定继承不同的对象,因为它要求在编译期间完全确定下来。 ### 总结 一条通用的准则是:**“用继承表达行为间的差异,并用字段表达状态上的变化**”。在上述例子中,两者都用到了:通过继承得到了两个不同的类,用于表达**act()**方法的差异:而**Stage**通过运用组合使自己的状态发生了变化。在这种情况下,这种状态的改变也就产生了行为的改变。
标签:
Java
,
Java编程思想
,
JavaSE
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://www.lilinchao.com/archives/16.html
上一篇
协变返回类型
下一篇
JVM学习一 -- 浅谈类的加载过程
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
FileBeat
算法
Java
JavaWEB项目搭建
nginx
Elasticsearch
数据结构和算法
Spring
Kibana
Hadoop
Hive
DataX
Kafka
JavaSE
Golang基础
Sentinel
序列化和反序列化
稀疏数组
容器深入研究
GET和POST
Spark RDD
Spark Core
Thymeleaf
MyBatis
队列
Stream流
二叉树
并发编程
随笔
ClickHouse
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞