李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
用继承进行设计
Leefs
2019-10-16 AM
1692℃
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://lilinchao.com/archives/16.html
上一篇
协变返回类型
下一篇
JVM学习一 -- 浅谈类的加载过程
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
Spark RDD
gorm
MyBatis-Plus
VUE
Zookeeper
Kafka
DataWarehouse
字符串
Shiro
Jquery
Stream流
Hadoop
线程池
Git
微服务
Ubuntu
FileBeat
Linux
正则表达式
Tomcat
锁
JavaWEB项目搭建
Flume
前端
Python
二叉树
Http
Redis
数学
递归
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭