java组合优于继承

前言

对于类的扩展,大家知道有两种方式,一种是:继承和复合。
那么对于继承和复合,二者有什么差别呢?为什么说组合优于继承

正文

组合和继承的区别:
组合 继承
has-a is-a
不破坏封装 破坏封装,子类依赖父类
支持扩展,随意增加组合类 只能继承一个父类,必须包含所有方法,增加系统复杂性
  • 继承是is-a的关系,就像 鸟 是一种 动物。而 组合是has-a的关系,就像 鸟 有 动物的特征。
  • 继承破坏了封装性,因为子类依赖父类,而组合则不破坏封装性
  • 继承子类只能继承一个父类,同时必须包含所有的方法,而组合支持扩展,可以随意增加组合类。
继承是如何破坏封装性的

有一个通俗的例子,是靖凡大人举的例子:我想拿嘉美的杯子,但是这个杯子是属于嘉美,所以我要把嘉美搬出来,但是嘉美是属于森林,所以我要把森林搬出来……但是我们都忘了,我的初心是“拿嘉美的杯子”。

如何用组合来替换继承

看如下的例子:

public class A {
    //方法功能是说话
    public void say() {
        //一堆说话的实现细节
    }
    //方法功能是唱歌
    public void song() {
        //具体的实现细节
        // 唱歌的前提要先说话,所以调用自身的say()方法
        say();
        //然后一堆唱歌的实现细节
    }
}

public class B extends A{
    @Override
    public void say() {
        //我就想再说话之前先告诉大家一声我要说话了
        System.out.println("我要开始说话了");
        super.say();
    }

    @Override
    public void song() {
        //我就想再唱歌之前先告诉大家一声我要唱歌了
        System.out.println("我要开始唱歌了");
        super.song();
    }

    public static void main(String[] args) {
        B b = new B();
        //现在我要高歌一首
        b.song();
    }
}

结果

我要开始唱歌了
我要开始说话了

这结果怎么是这样子,我明明就是想唱歌呀,为啥又说我开始说话了,
其实是因为类B继承了类A ,在类A中的song实现细节中用了say()方法,导致在类B中先走了song()方法,又走了say()方法,但是对于类B来说我不想知道你走了啥方法,我就是想要的功能而已,唱歌就是唱歌,说话就是说话。当然我们也可以将类A中的song()方法改成不调用say()方法,但是这个不应该和类A的实现细节有关系啊,我只是提供了我的API接口,功能不变的情况下,我的内部实现细节怎么变都应该是没有问题的啊,所以这就是继承暴漏了API的实现细节出现的问题。
而复合就不会有这样的问题了,把类A做为一个私有域放入类B中。再调用类A的song()方法

public class B {
    private A a;

    public B(A a) {
        this.a = a;
    }
    public void say() {
        System.out.println("我要开始说话了");
        a.say();
    }

    public void song() {
        System.out.println("我要开始唱歌了");
        a.song();
    }
    
    public static void main(String[] args) {
        B b = new B(new A());
        //现在我要高歌一首
        b.song();
    }
}

结果

我要开始唱歌了

可以看出复合屏蔽了类的实现细节,专注于功能而不关注细节

所以继承要严格的遵循is-a的关系,否则不能瞎用继承,在用继承的时候想好继承是不是只是为了扩展功能。否则就不得不用复合来代替继承了。

例子来自于:https://blog.csdn.net/weixin_44130081/article/details/90375829

发布了262 篇原创文章 · 获赞 201 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/hdy14/article/details/97923364
今日推荐