zoukankan      html  css  js  c++  java
  • 面向对象理论知识

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

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

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

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

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

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

    总结:

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

  • 相关阅读:
    剑指offer--03.从尾到头打印链表
    剑指offer--02.替换空格
    剑指offer--01.二维数组中的查找
    JAVA日记之mybatis-3一对一,一对多,多对多xml与注解配置
    SpringBoot 2.x 自定义拦截器并解决静态资源访问被拦截问题
    springboot项目WEB-INF 目录 jsp页面报404
    Spring Boot 配置拦截器方式
    通过idea创建Maven项目整合Spring+spring mvc+mybatis
    idea创建maven项目
    PLSQL操作Oracle创建用户和表
  • 原文地址:https://www.cnblogs.com/fanfan-90/p/13291819.html
Copyright © 2011-2022 走看看