博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多用组合,少用继承
阅读量:4977 次
发布时间:2019-06-12

本文共 2238 字,大约阅读时间需要 7 分钟。

  一般情况下,继承(主要是由类实现)可能比组合(主要是由接口实现)更好实现,而且继承似乎有种一劳永逸的牛叉功能。这篇随笔是我读过一篇文章之后的一些想法,欢迎各位指教讨论。

  一般情况下,我们总是花许多时间在系统的维护和变化上,有时会比开发花的时间更多,所以我们应该致力于提高可维护性和可扩展性上的复用程度,而继承在这方面可能略逊于组合,当然也有特殊情况。。。

  使用组合建立的系统具有很大的弹性,不仅可以将算法族封装成类,更可以在运行时动态地改变行为,只要组合的行为对象符合正确的接口标准即可。

  下面用一些代码来具体说说。。。还是用中的例子。

public abstract class Cat  {    IEatBehavior pEatBehavior;   // 为行为接口定义一个引用变量    public void Eat()    {      pEatBehavior.Eat();     }    public void Drink()    {      System.Out.Println(" I Drink Water.");    }  }  public class WhiteCat Extends Cat  {    public WhiteCat()    {      pEatBehavior = new WhiteCatEatBehaviorClass();   // WhiteCatEatBehaviorClass 是实现接口 IEatBehavior 的一个具体类,                                      // 里面的细节可以不用管,                                     // 你只需要知道这是白猫特有的吃法就行了                                  }  }

 

  现在白猫也有自己 不同于 超类中的喝,如果使用继承的话,只要覆盖超类中的方法Drink()即可,但想一想,如果有很多子类继承该超类呢,那就得一个一个的覆盖,这可是体力活了。。。所以觉得在这使用组合可能更合适一点,现在就干起来,首先来新建一个含有Drink()方法的接口和一些具体类。 

public interface IDrinkBehavior  {    public Drink();  }  public class WhiteCatDrinkBehavior implements IDrinkBehavior  {    public void Drink()    {      System.Out.Println(" I Drink Soup.");    }  }

 

  下面让我们再重新写一下超类及它的子类

public abstract class Cat  {    IEatBehavior pEatBehavior;         // 为吃行为接口定义一个引用变量    IDrinkBehavior pDrinkBehavior;     // 为喝行为接口定义一个引用变量,有了这个变量,原来的Drink()方法就可以简化了    public void Eat()    {      pEatBehavior.Eat();    }    public void Drink()    {      pDrinkBehavior.Drink();       // 直接委托给 pDrinkBehavior 对象办就可以了    }  }  public class WhiteCat Extends Cat  {    public WhiteCat()    {      pEatBehavior   = new WhiteCatEatBehaviorClass();       pDrinkBehavior = new WhiteCatDrinkBehaviorClass();    // 实例化一下,指明 喝 这个行为委托给哪个具体类来执行    }  }

 

  上面提到了可以在运行时动态地改变行为,这里也介绍一下实现方法,我们可以在超类中,加入两个方法:

  

public abstract class Cat{    // 之前的方法,变量不变    // 添加的方法    public Void SetEatBehavior(IEatBehavior pNewEatBehavior)    {        pEatBehavior = pNewEatBehavior;    }    public Void SetDrinkBehavior(IDrinkBehavior pNewDrinkBehavior)    {        pDrinkBehavior = pNewDrinkBehavior;    }}

 

  这样就可以在运行时调用SetEatBehavior,SetDrinkBehavior方法动态地改变行为了(组合的一大优点)。一般情况下,对象的 多种不同行为 适合 组合 来组织,而 静态的状态,类型等 适合 继承 来组织(这只是一家之说,仅参考)。。。

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/hachun/p/3456661.html

你可能感兴趣的文章
用JAVA编写浏览器内核之实现javascript的document对象与内置方法
查看>>
centos iptables
查看>>
unity3d 移动与旋转 2
查看>>
寻找二叉查找树中比指定值小的所有节点中最大的那个节点
查看>>
如何设置输入框达到只读效果
查看>>
RT3070 USB WIFI 在连接socket编程过程中问题总结
查看>>
MIS外汇平台荣获“2013年全球最佳STP外汇交易商”
查看>>
LeetCode 题解之Add Digits
查看>>
hdu1502 , Regular Words, dp,高精度加法
查看>>
SpringBoot在idea中的热部署配置
查看>>
MyEclipse连接SQL Server 2008数据库的操作方法
查看>>
JS验证图片格式和大小并预览
查看>>
laravel5.2 移植到新服务器上除了“/”路由 ,其它路由对应的页面显示报404错误(Object not found!)———新装的LAMP没有加载Rewrite模块...
查看>>
编写高质量代码--改善python程序的建议(六)
查看>>
windows xp 中的administrator帐户不在用户登录内怎么解决?
查看>>
接口和抽象类有什么区别
查看>>
Codeforces Round #206 (Div. 2)
查看>>
**p
查看>>
优先队列详解
查看>>
VS2012 创建项目失败,,提示为找到约束。。。。
查看>>