• 面向对象理论知识


    为什么优先使用组合而不是继承

    继承的起源,来自于多个类中相同特征和行为的抽象。子类可以通过继承父类,那么可以调用父类中定义的方法和属性,从而达到代码重用的目的。另外,子类除了重用父类的代码以外,还可以扩展自身的属性和方法,来描述子类特有的特征和行为。

    例如:人类和马类这两个类,有什么共同的特征和行为呢?都有年龄,都要呼吸,都可以行动,都要吃奶。我们可以把人类和马类相同的特征和行为抽取出来,形成一个父类:哺乳动物。人类和马类只要继承哺乳动物这个父类。那么,就可以直接重用哺乳动物父类中定义的属性和行为,相同的属性和行为就可以不用再重复描述。所以,通过继承,可以达到代码很大的重用。
    除此之外,人类和马类还可以再定义自己本身的特征和行为。比如,马要吃草,人可以说话。那么,人类和马类可以在继承了哺乳动物父类的同时,再定义说话或吃草的行为,来扩展自身的特征和行为。

    使用继承有很多优点,父类的大部分功能可以通过继承关系自动进入子类;
    但是,继承同样有很多缺点:

    • 类只能单根继承。也就是说,一个类只能有一个父类,不能同时继承两个父类。所以,从这里就可以看出继承的其中一个缺点:无法通过继承的方式,重用多个类中的代码。
    • 父类的属性和方法,子类是无条件继承的。也就是说,不管子类愿意不愿意,都必须继承父类所有的属性和方法,容易造成方法的污染。
    • 从父类继承而来的实现是静态的,不能在运行时发生改变,不够灵活。无论是从父类中继承的方法,还是子类重写的父类方法,实现的都是一种静态的复用。不能在运行时发生改变,灵活性比较差。

    通过聚合/组合关系,可以解决继承的缺点。由于一个类可以建多个属性,也就是可以聚合多个类。所以,可以通过聚合/组合关系,重用多个类中的代码。
    另外,我们可以选择一个类中是否应该具有某种行为,从而决定应该聚合那些类,不应该聚合那些类。这样,通过聚合/组合关系,也可以避免继承所带的方法污染问题。所以,使用聚合/组合,具有很强的代码重用性和灵活性。
    聚合/组合复用也可以在运行时动态进行。新对象可以使用聚合/组合关系,将新的责任委派到合适的对象。
    这样的解决方案,其实就是告诉我们,与其我们”是什么”,倒不如我们”用什么”。也就是用聚合/组合复用,去代替继承复用。把一些特征和行为抽取出来,形成工具类。然后通过聚合/组合成为当前类的属性。再调用其中的属性和行为达到代码重用的目的。
    换句话说,用”has-a”(有什么或用什么)去替代”is-a”(是什么)。

    总结:

    继承和聚合/组合都可以达到代码重用的目的。继承有自身的优点,父类的大部分功能可以通过继承关系自动进入子类;修改或扩展继承而来的实现较为容易。
    继承可以用,但使用继承需要谨慎。一般来说,使用继承有两个条件:
    父类中所有的属性和方法,在子类中都适用。
    子类不需要再去重用别的类中的代码。如果不能满足这两个条件,那么就应该使用聚合/组合关系去替代继承,来达到代码的复用。

  • 相关阅读:
    [转]android Intent机制详解
    [转]Android进程与线程基本知识
    HTML背景图片自适应
    边框边界填充理解
    [转]Android 代码自动提示功能
    [转]Windows7:Visual Studio 2008试用版的评估期已经结束解决方法
    eclipse安装、汉化、搭建安卓开发环境
    asp.net控件拖不动。控件错误
    opengl 入门浅学(一)
    opengl 无法定位程序输入点_glutInitWithExit于动态链接库glut32.dll上
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13291819.html
Copyright © 2020-2023  润新知