• 继承和组合的比较


    面向对象系统中功能复用的两种最常用技术是类继承和对象组合(object composition)。正
    如我们已解释过的,类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子
    类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方
    式中,父类的内部细节对子类可见。
    对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象
    来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用
    (black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。
    继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,因为程序设
    计语言直接支持类继承。类继承可以较方便地改变被复用的实现。当一个子类重定义一些而
    不是全部操作时,它也能影响它所继承的操作,只要在这些操作中调用了被重定义的操作。
    但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行
    时刻改变从父类继承的实现。更糟的是,父类通常至少定义了部分子类的具体表示。因为继
    承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性” [ S n y 8 6 ]。子类中的
    实现与它的父类有如此紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生
    变化。
    当你需要复用子类时,实现上的依赖性就会产生一些问题。如果继承下来的实现不适合
    解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最
    终限制了复用性。一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。
    对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼
    此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象
    一起使用。这还会产生良好的结果:因为对象只能通过接口访问,所以我们并不破坏封装
    性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的
    实现是基于接口写的,所以实现上存在较少的依赖关系。
    对象组合对系统设计还有另一个作用,即优先使用对象组合有助于你保持每个类被封装,
    并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控
    制的庞然大物。另一方面,基于对象组合的设计会有更多的对象(而有较少的类),且系统的行
    为将依赖于对象间的关系而不是被定义在某个类中。
    这导出了我们的面向对象设计的第二个原则:
    优先使用对象组合,而不是类继承。
    理想情况下,你不应为获得复用而去创建新的构件。你应该能够只使用对象组合技术,
    通过组装已有的构件就能获得你需要的功能。但是事实很少如此,因为可用构件的集合实际
    上并不足够丰富。使用继承的复用使得创建新的构件要比组装旧的构件来得容易。这样,继
    承和对象组合常一起使用。
    然而,我们的经验表明:设计者往往过度使用了继承这种复用技术。但依赖于对象组合
    技术的设计却有更好的复用性(或更简单)。你将会看到设计模式中一再使用对象组合技术。
     
    --------------------------------------------------------------------------------------------------------------------------------------
     

    根据网络上大家对继承和组合的讨论,我简单总结以下几点: 1)组合(has-a)关系可以显式地获得被包含类(继承中称为父类)的对象,而继承(is-a)则是隐式地获得父类的对象,被包含类和父类对应,而组合外部类和子类对应。

    2)组合关系在运行期决定,而继承关系在编译期就已经决定了。

    3)组合是在组合类和被包含类之间的一种松耦合关系,而继承则是父类和子类之间的一种紧耦合关系。
    4)当选择使用组合关系时,在组合类中包含了外部类的对象,组合类可以调用外部类必须的方法,而使用继承关系时,父类的所有方法和变量都被子类无条件继承,子类不能选择。
    5)最重要的一点,使用继承关系时,可以实现类型的回溯,即用父类变量引用子类对象,这样便可以实现多态,而组合没有这个特性。
    6)还有一点需要注意,如果你确定复用另外一个类的方法永远不需要改变时,应该使用组合,因为组合只是简单地复用被包含类的接口,而继承除了复用父类的接口外,它甚至还可以覆盖这些接口,修改父类接口的默认实现,这个特性是组合所不具有的。
    7)从逻辑上看,组合最主要地体现的是一种整体和部分的思想,例如在电脑类是由内存类,CPU类,硬盘类等等组成的,而继承则体现的是一种可以回溯的父子关系,子类也是父类的一个对象。

    8)这两者的区别主要体现在类的抽象阶段,在分析类之间的关系时就应该确定是采用组合还是采用继承。

    9)引用网友的一句很经典的话应该更能让大家分清继承和组合的区别:组合可以被说成“我请了个老头在我家里干活” ,继承则是“我父亲在家里帮我干活"。

  • 相关阅读:
    expdp定时备份
    设计模式简介
    利用Python制作万年历
    Linux下Python的安装
    排序算法-直接插入排序
    排序算法-冒泡排序
    数据结构-循环顺序队列&链队列
    数据结构-栈&链栈
    数据结构-双向链表&双向循环链表
    数据结构-单链表&单循环链表
  • 原文地址:https://www.cnblogs.com/heartstage/p/3390991.html
Copyright © 2020-2023  润新知