为什么不通过修改接口或者选择书写继承接口重写方法的新子类,偏偏选择添加上一个装饰器
一乐乐 人气:0为什么不通过修改接口或者选择书写继承接口的新子类,偏偏选择添加上一个装饰器?
1.盆友们,其实这个问题挺简单的,还记得单纯我们为啥选择定义接口呀抽象类呀(这些框架、模板的)吗?
大白话--“方便批量生产”+ “不破坏原有类结构”。(最后会放上接口和继承重写的作用的哈)
记住“方便批量生产” + 不破化基础上再扩展,现在回过头来思考添加装饰器的作用就很简单啦。
在实际的应用开发中,我们知道,实现了一开始定义好的接口的子类已经有好多个了,但是现在我们有了新的需求是想要拥有好多个在原来子类的继承上功能得到扩展的新子类。于是乎,为了批量生产这批添加了新功能的子类,我们选择了装饰器,做到了在不破坏原有的类的结构基础上进行扩展。同时还避免了两个尴尬:
(1)如果选择修改原来接口导致的麻烦是,原来那批实现接口的子类都需要需改了;
(2)如果选择在实现原来接口的基础上,每个实现类添加上新功能,太多子类啦!!!
2.所以我们选择了装饰器(封装原有的类,通过依赖关系实现扩展功能)。
首先我们定义了一个抽象类的装饰器实现原来接口,然后定义一个接口对象属性,(为了封装原有的类),通过定义带参构造方法,把接口对象作为参数。装饰器的好处是做到了不破坏原有的类的结构的基础进行了扩展。
为啥要定义成抽象类的装饰器呢,复习一下抽象类的作用就迎刃而解啦。
3.代码应用举例:
package BiscuitsDemo; public class BiscuitsTest { public static void main(String[] args) { //定义一个圆形烧饼对象 // Biscuits biscuits = new RoundedBiscuits(); //使用多态啦 RoundedBiscuits biscuits = new RoundedBiscuits(); PetaloidBiscuits petaloidBiscuits = new PetaloidBiscuits(biscuits); petaloidBiscuits.rounded(); } }
package BiscuitsDemo; /** * 烧饼接口,定义烙印圆形烧饼抽象方法 * @author * */ public interface Biscuits { //烙印圆形烧饼 void rounded(); }
package BiscuitsDemo; /** * 圆形烧饼类(常见烧饼) * @author * */ public class RoundedBiscuits implements Biscuits { @Override public void rounded() { System.out.println("新鲜出炉 圆乎乎的烧饼呀,圆乎乎"); } }
package BiscuitsDemo; /** * 烧饼装饰抽象类 * @author * */ public abstract class DecoratorBiscuits implements Biscuits{ Biscuits biscuits; //定义烧饼接口对象,通过带参构造方法封装烧饼接口对象 public DecoratorBiscuits(Biscuits biscuits) { this.biscuits = biscuits; } } package BiscuitsDemo; /** * 添加了花瓣轮廓的烧饼烧饼类 * @author * */ public class PetaloidBiscuits extends DecoratorBiscuits{ public PetaloidBiscuits(Biscuits biscuits) { super(biscuits); } @Override public void rounded() { //调用实际干活对象的rounded()方法 biscuits.rounded(); petaloid(); //添加花瓣轮廓,扩展功能 } //花瓣轮廓 private void petaloid() { System.out.println("像花一样的烧饼来咯"); } }
运行结果:
最后ps:
1.接口(统一规范):
-
1.使设计、实现完全分离
-
2、更加自然地使用多态
-
3.更容易搭建程序的框架,更容易替换实现
2.继承:[也叫扩充](is-a 的关系)
-
(公共内容,放在父类)提高代码重用性,
-
(方便修改)提高维护性
-
类与类之间有了关系,多态的前提
3.重写,方法重写又称[方法覆盖]:子类重写父类的方法。
重写好处:重写实现类的扩充,子类拥有了一种选择权:继承父类的方法实现细节,或者自己重写方法实现细节覆盖原有的方法的细节。(如果实例化子类对象,则调用的方法是子类重写的方法。)
当子类可继承父类,子类便拥有了父类的属性和方法,就不用再编写同样的方法,但是想拥有自己的实现方式,就需要重写覆盖继承来自父类的方法。
参考资料:https://www.imooc.com/article/24027 (Java设计模式(9)----------装饰器模式)
加载全部内容