设计模式(05)——组合和继承

组合和继承

继承带来的问题

《面向对象以及特性分析》文章,我们可以看到继承带来的问题:

  1. 菱形问题;
  2. 继承层次过深过复杂。


image.png

如上图所示,因为每个鸟根据特性会有会飞或者不会飞的特性,也会有会叫不会叫的特性等等,如果根据这些特性来设计类,然后让对应的终点类来继承的话,那么则会造成类的膨胀,从而代码变得十分的复杂。

组合的优势

针对上述继承所带来的问题,我们可以通过组合、委托、接口 3个技术手段,来进行另一种层面上的实现,具体代码如下。

// ================================  接口定义 ==============================================
public interface Flyable{
	void fly();
}

public interface Tweetable{
	void tweet();
}

public interface EggLayable{
	void layEgg();
}

// ================================   委托类(通过在委托类中定义具体的代码实现,从而使用 组合 的形式来消除重复代码,做到复用)  ==============================================
public class FlyAbility implements Flyable{
	@Override
    public void fly(){
    	// 具体实现
    }
}

public class TweetAbility implements Tweetable{
	@Override
    public void tweet(){
    	// 具体实现
    }
}

public class EggLayAbility implements EggLayable{
	@Override
    public void layEgg(){
    	// 具体实现
    }
}

// ==============================  具体类   ================================================
public class Ostrich implements Tweetable,EggLayable{
    // 组合上层实现
    private TweetAbility tweetAbility = new TweetAbility();
    private EggLayAbility eggLayAbility = new EggLayAbility();
    
    // 通过组合,就不需要编写重复代码
    @Override
    public void tweet(){.
        tweetAbility.tweet();
    }
    
    @Override
    public void layEgg(){
    	eggLayAbility.layEgg();
    }
}

public class Sparrow implements Flyable,Tweetable,EggLayable{
    private FlyAbility flyAbility = new FlyAbility();
    private TweetAbility tweetAbility = new TweetAbility();
    private EggLayAbility eggLayAbility = new EggLayAbility();
    
    @Override
    public void fly(){.
        flyAbility.fly();
    }
    
    @Override
    public void tweet(){.
        tweetAbility.tweet();
    }
    
    @Override
    public void layEgg(){
    	eggLayAbility.layEgg();
    }
}

使用时机

根据上面的分析,可能觉得既然继承有那么多的问题,那干脆就不要用了吧,全都用组合多好。

其实不是这样的,继承和组合都各自有其代表的语义。

  • 继承代表的是 is-A 关系,代表子类是父类的一种特殊情况;
  • 组合代表的是 has-A 关系,代表的是被组合的类是父类的一部分;

此外继承还用简单易理解的方式,实现了代码的复用,因此如果逻辑比较简单,还是可以使用继承的。具体使用方式就需要开发人员根据具体情况具体分析了。

公众号截图




文章在公众号「iceWang」第一手更新,有兴趣的朋友可以关注公众号,第一时间看到笔者分享的各项知识点,谢谢!笔芯!

posted @ 2020-11-11 15:01  iceWang丶  阅读(267)  评论(0编辑  收藏  举报