继承和组合模式

继承属于OO三大特性之一,往往其提供的复用性让人称道,但是它也带来了严重的问题:继承严重地破坏了父类的封装性。在继承关系中,子类可以直接访问父类中的Field和方法,从而造成子类和父类的严重耦合。并且,子类在继承中拥有的重写更是加重了继承的危害:重写父类已有方法,将子类实例赋给父类引用,编译时是父类,而真正运行时却成了子类。这就是偷天换日,如:

Animal a  = new Bird();

a.breath();

这种情况有可能被别人利用。

这是我们需要考虑使用另外一种复用的方法:组合模式。组合模式的方法是用一个class成为另一个class的一部分来实现复用的。

首先我们先看看继承的实现:

package test.testinherite;

//定义一个刺客的类
class Cike
{
    public void tujin()
    {
        System.out.println("刺客一般都有突进技能");
    }
    
    public void shouge()
    {
        System.out.println("刺客一般都能够收割人头");
    }
}

class AKL extends Cike
{
    public void fangwu()
    {
        System.out.println("AKL有保护技能——放雾");
    }
}

class Kate extends Cike
{
    public void tiao()
    {
        System.out.println("卡特只能跳来跳去");
    }
}

public class InheritTest {
    public static void main(String[] args)
    {
        AKL akl =  new AKL();
        akl.tujin();
        akl.shouge();
        akl.fangwu();
        
        Kate kate = new Kate();
        kate.tujin();
        kate.shouge();
        kate.tiao();
    }
}

接下来看看组合:

package test.testforcomposite;


//定义一个刺客的类
class Cike{
    public void tujin()
    {
        System.out.println("刺客一般都有突进技能");
    }
    
    public void shouge()
    {
        System.out.println("刺客一般都能够收割人头");
    }
}

class AKL{
    private Cike cike = new Cike();
    public AKL(Cike cike)
    {
        this.cike = cike;
    }
    
    public void tujin()
    {
        cike.tujin();
    }
    
    public void shouge()
    {
        cike.shouge();
    }
    
    public void fangwu()
    {
        System.out.println("AKL有保护技能——放雾");
    }
}

class Kate{
    private Cike cike = new Cike();
    public Kate(Cike cike)
    {
        this.cike = cike;
    }
    
    public void tujin()
    {
        cike.tujin();
    }
    
    public void shouge()
    {
        cike.shouge();
    }
    
    public void tiao()
    {
        System.out.println("卡特只能跳来跳去");
    }
}

public class CompositeTest {
    public static void main(String[] args)
    {
        Cike cike = new Cike();
        AKL akl =  new AKL(cike);
        akl.tujin();
        akl.shouge();
        akl.fangwu();
        
        Kate kate = new Kate(cike);
        kate.tujin();
        kate.shouge();
        kate.tiao();
    }
}

我们可以看到两者实现的效果是一样的。组合中利用AKL和Kate的构造器引入Cike,并在其方法中完成复用Cike的方法。

总结一下:

继承要表达的是一种“是(is a)”关系,而组合表达的是“有(has a)”的关系。

你可能感兴趣的:(继承,组合模式)