• 继承与组合


    一、继承(继承强调的是is-a的关系)

    一、继承的优点

    1)Java语言不支持类的多重继承,也就是说,一个子类做多只能有一个父类 。如果要想实现多重继承,只能通过接口的多重继承来实现。

    2)子类只能继承父类的非私有(public、protected)的成员变量和方法。

    3)当子类中定义的成员变量与父类中的成员变量重名时,子类中的成员变量会覆盖父类中的成员变量,而不是继承父类中的成员变量。

    4)当子类中的方法签名与父类中的方法签名相同(重名)时(前提是个数相同、方法类型相同),子类会覆盖父类中的方法,也不会继承。

    二、继承的缺点

    (1) 继承破坏封装性

    给父类增加了一个方法A,这时子类与父类之间就可能越来越脱离is-a
    举个例子:比如,鸟类有羽毛等属性,这里有一个需求是,定义一个有羽毛的鸡类,采用继承的方法很优雅也很方便,直接一个extends 就可以实现,但是如果有一天,这个鸟类添加了一个飞翔的公有方法,此前继承了鸟类的鸡类会自动继承了这个方法,鸡会飞翔?顶多就是矮距离飞跃。此时给鸡飞的方法就是破坏了鸡的封装性,鸡不应该有此方法。此时的鸡已经和有飞翔行为的鸟类之间不是is-a 关系了。

    (2) 继承是紧耦合:

    继承紧耦合体现在父类变就会影响子类,此时子类如果因此需要修改,重构的难度可能会很高。

    (3) 子类对父类的扩展往往会增加系统结构复杂度

    继承树深度加深,结构越复杂。

    (4) 不支持在运行时指定父类

    (5) 子类不能改变父类的接口

    二、组合(组合强调的是has-a的关系。)

    一、什么是组合

    组合是一种较弱的关系,是has-a的关系,给个代码:

    1 public class Animal {
    2     private void beat(){
    3         System.out.println("心脏跳动...");
    4     }
    5     public void breath(){
    6         beat();
    7         System.out.println("呼吸中...");
    8     }
     1 public class Bird {
     2     //将Animal作为Bird的成员变量
     3     private Animal a;
     4     public Bird(Animal a){
     5         this.a = a;
     6     }
     7     public void breath(){
     8         a.breath();
     9     }
    10     public void fly(){
    11         System.out.println("我在飞..");
    12     }
    13  
    14     public static void main(String[] args){
    15         Animal animal = new Animal();
    16         Bird b = new Bird(animal);
    17         b.breath();
    18         b.fly();
    19     }
    20 }

    二、组合的优点

    • 组合不破坏封装,相对于继承
    • 组合松耦合,包装类和被包装类彼此独立,不会因为被包装类突然加个方法就使得包装类多了一个方法,包装类视情况包装所需方法。
    • 支持动态组合,组合的方式在运行时可以根据条件来选择所组合的类。
    • 包装类可以通过包装改变被包装类的接口,比如被包装类是实现了Set接口的,我可以通过包装,让包装类实现Map接口。

    三、组合的缺点

    • 不能实现多态
    • 无法自动获得被包装类的接口,比如被包装类实现了Set接口,包装类并没有自动获得此接口,需要经过包装,才有可能和他一样的接口。

    三、什么情况下使用继承,什么情况下使用组合

    • 1.如果两个类的关系不是“is-a”的关系,最好就不要用继承;不要为了减少代码或者提高代码的复用性而使用继承,而导致后期代码结构被破坏,造成代码的 可维护性差。一旦父类被修改,就会影响到其继承的子类,从而增加维护难度和成本(需求老是改的话,牵一发而动全身)。
    • 2.不要因为实现多态而使用继承,如果class之间没有extends的关系,就可以通过接口与组合的方式来达到相同的目的。设计模式中的策略模式就是对这一点很好的体现,采用接口与组合的方式比采用继承的方式有更好的可拓展性。
    • 一切都是为了提高代码的复用性(代码重构的原因),避免代码的臃肿,造成后期可维护性变差造成的成本增加。
  • 相关阅读:
    2018山东省赛补题
    USACO 2006 November Gold Corn Fields /// 状压 oj23941
    East Central North America 2006 Hie with the Pie /// 状压dp oj22470
    USACO 2003 Fall Orange Cow Exhibition /// 负数01背包 oj22829
    UASCO Cow Pedigrees /// oj10140
    滑雪 矩阵中的最长上升路径 /// 记忆化DFS || DP oj22919
    十四届华中科大赛补题
    USACO 2007 February Silver The Cow Lexicon /// DP oj24258
    POJ 3252 区间内一个数的二进制中0的数量要不能少于1的数量(数位DP)
    HDU 4734 F(x) (数位DP)
  • 原文地址:https://www.cnblogs.com/qiaoxin11/p/12543537.html
Copyright © 2020-2023  润新知