面向对象中组合和继承的关系

在面向对象的过程中,常用的两个功能复用是类继承和组合(object composition)

     类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言的,在继承方式中,父类的内部细节对子类可见。

     新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。

     类继承的优点和不足之处:

     类继承是在编译时刻静态定义的,且可直接使用,程序设计语言直接支持类继承。类继承可以较方便地改变被复用的实现。当一个子类重定义父类的部分实现时,它也能影响它所继承的操作。

类继承不足之处在于继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。继承对子类暴露了其父类的实现细节,所以继承常被认为“破坏了封装性”。子类与父类存在着很强的依赖关系,父类实现中的任何变化必然会导致子类发生变化。如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用

性。一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。

  对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象一起使用。对象只能通过接口访问,只要类型一致,运行时刻还可以用一个对象来替代另一个对象;对象的实现是基于接口写的,所以实现上存在较少的依赖关系。

对象组合对系统设计优先使用对象组合有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。另一方面,基于对象组合的设计会有更多的对象(而有较少的类),且系统的行为将依赖于对象间的关系而不是被定义在某个类中。这就是的面向对象设计的第二个原则:优先使用对象组合,而不是类继承 

     理想情况下,你不应为获得复用而去创建新的构件。你应该能够只使用对象组合技术,通过组装已有的构件就能获得你需要的功能。但是事实很少如此,因为可用构件的集合实际上并不足够丰富。使用继承的复用使得创建新的构件要比组装旧的构件来得容易。这样,继承和对象组合常一起使用。

     然而,经验表明:设计者往往过度使用了继承这种复用技术。但依赖于对象组合技术的设计却有更好的复用性(或更简单)。你将会看到设计模式中一再使用对象组合技术。

     组合较继承的优势:

1  组合允许将问题分割成互不依赖的子元件。每个元件可以由不同的开发者开发。

2  组合比继承有更少的耦合,继承强制了继承类与被继承类之间的耦合,但是组合不会。

3  组合会更少的代码冗余,继承比较容易导致冗余。B继承A,在很多时候,B只会用到A部分,不需要的部分则成了冗余。组合完全                                                      可以避免这些情况。         

4  组合有更好的封装,组合是基于公开接口的,每一个元件都不知道它内部的实现细节。而继承则会把父类内部实现

      暴露给子类。

5  组合更容易更改,任何元件都可以被更改而保证对其它元件影响很小,只要保证公开的接口不变。

       组合的不足:为了实现功能,会有很多的小模块

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

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

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

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

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

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

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

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

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

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

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

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

 

最近在学设计模式,把好的重要的东西都慢慢总结起来,好好加油!!!



posted @ 2013-05-28 20:00  旧事乡里人  阅读(244)  评论(0编辑  收藏  举报