再论组合与继承

被架构师问的面试题

      在本书中,把UML中的关联关系和聚集关系统称为组合关系。组合与继承都是提高代码可重用性的手段。在设计对象模型时,可以按照语义来识别类之间的组合关系和继承关系。在有些情况下,采用组合关系或者继承关系能完成同样的任务,组合和继承存在着对应关系:组合中的整体类和继承中的子类对应,组合中的局部类和继承中的父类对应,参见表6-1。本章6.9节(小结)中的表6-2总结了组合与继承的优缺点。


表6-1 组合与继承的对应关系

组 合 关 系

继 承 关 系

局部类

父类

整体类

子类

从整体类到局部类的分解过程

从子类到父类的抽象过程

 

从局部类到整体类的组合过程

从父类到子类的扩展过程

 

 

值得注意的是,本章所说的整体类和局部类比UML的聚集关系中的整体类和局部类具有更广泛的含义。在本章中,如果在类A中包含类C类型的属性,那么就把类A称为整体类或者包装类,把类C称为局部类或者被包装类。

组合关系的分解过程对应继承关系的抽象过程

 


图6-11 具有相同行为的类A和类B

      下面的例子未涉及具体的业务领域,该例子分别用组合关系与继承关系来建立一个对象模型。如图6-11所示,类A和类B有相同方法method1()、method2()和method3(),此外类A和类B还分别拥有methodA()和methodB()方法。在method3()方法中访问method1()方法,在mehodA()和methodB()方法中都会访问method2()方法。以下是类A和类B的源程序。


 

图6-12 从类A和类B中抽象出父类C

1.使用继承关系

      在图6-12中,从类A和类B中抽象出父类C,它包含method1()、method2()和method3()方法。由于在类A和类B中都会访问method2()方法,因此把method2()方法声明为protected类型。


2.使用组合关系

      在图6-13中,类A与类C,以及类B与类C之间为组合关系。在类A中定义了C类型的引用变量c,类A的method3()方法直接调用类C的method3()方法。类A对类C进行了封装,类A被称为包装类,同样,类B也是包装类。由于在类A和类B中都会访问private类型的method2()方法,因此不能把method2()方法放在类C中定义,因为如果这样做,就必须在类C中把method2()方法定义为public类型,而这彻底破坏了封装。以下是类C、类A和类B的源程序。


图6-13 从类A与类B中分解出局部类C


      组合关系和继承关系相比,前者的最主要优势是不会破坏封装,当类A与类C之间为组合关系时,类C封装实现,仅向类A提供接口;而当类A与类C之间为继承关系时,类C会向类A暴露部分实现细节。在软件开发阶段,组合关系虽然不会比继承关系减少编码量,但是到了软件维护阶段,由于组合关系使系统具有较好的松耦合性,因此使得系统更加容易维护。

组合关系的缺点是比继承关系要创建更多的对象。以下程序演示在两种关系下创建类A的实例并且调用其methodA()方法。


      从以上程序看出,对于组合关系,创建整体类的实例时,必须创建其所有局部类的实例;而对于继承关系,创建子类的实例时,无须创建父类的实例。继承关系最大的弱点是打破了封装,子类能够访问父类的实现细节,子类与父类之间紧密耦合,子类缺乏独立性,从而影响了子类的可维护性。为了尽可能地克服继承的这一缺陷,应该遵循以下原则:

·精心设计专门用于被继承的类,继承树的抽象层应该比较稳定。

·对于父类中不允许覆盖的方法,采用final修饰符来禁止其被子类覆盖。

·对于不是专门用于被继承的类,禁止其被继承。

·优先考虑用组合关系来提高代码的可重用性。

本章对组合关系和继承关系进行了比较,表6-2对这两种关系的优缺点做了总结。


表6-2 比较组合关系与继承关系

组 合 关 系

继 承 关 系

优点:不破坏封装,整体类与局部类之间松耦合,彼此相对独立

缺点:破坏封装,子类与父类之间紧密耦合,子类依赖于父类的实现,子类缺乏独立性

优点:具有较好的可扩展性

缺点:支持扩展,但是往往以增加系统结构的复杂度为代价

优点:支持动态组合。在运行时,整体对象可以选择不同类型的局部对象

缺点:不支持动态继承。在运行时,子类无法选择不同的父类

优点:整体类可以对局部类进行包装,封装局部类的接口,提供新的接口

缺点:子类不能改变父类的接口

缺点:整体类不能自动获得和局部类同样的接口

优点:子类能自动继承父类的接口

缺点:创建整体类的对象时,需要创建所有局部类的对象

优点:创建子类的对象时,无须创建父类的对象

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值