首先,我们来看一看继承的好处。
设计一个鸭子类Duck:
public class Duck { public Duck() { System.out.println("i an a duck"); } public void fly(){ System.out.println("飞"); }; public void swim(){ System.out.println("游泳"); } public void quack(){ System.out.println("ga~ga~ga"); } public void display(){ System.out.println("描述一下自己"); } }
现在有个子类绿头鸭GreenHeadDuck:
public class GreenHeadDuck extends Duck { public GreenHeadDuck() { System.out.println("I am a greenHeadDuck"); } public void head(){ System.out.println("我的头的绿的。。。。。。"); } @Override public void display() { System.out.println("我是绿头鸭"); } public void display(String name) { System.out.println("我叫" + name); } }
继承的好处就是,可以重写父类的方法display(),也可以重构父类的方法display(String name),也可以另外写自己的实现head(),都不影响。
现在设计另外一个子类:玩具小黄鸭BathDuck():
问题来了,小黄鸭会叫,但是小黄鸭不会飞,所以对BathDuck来说,fly()方法是无用的,多余的,但是继承规定了子类会继承父类所有的方法。这时候就要用组合。组合可以简单的理解成“有一个”。具体看代码。
看Duck类:
public class Duck { public void fly(){ System.out.println("飞"); }; public void swim(){ System.out.println("游泳"); } public void quack(){ System.out.println("ga~ga~ga"); } public void display(){ System.out.println("我是一只鸭子"); } }
Duck类几乎不变的,看看BathDuck类:
public class BathDuck { private Duck duck; public BathDuck(Duck duck) { this.duck = duck; } public void display() { this.duck.display(); } public void swim(){ System.out.println("我只我会浮在水面上,风往哪吹,我往哪游!!"); } }
对于自己不需要的方法,完全就不会加载进来,需要的可以用Duck对象去调用duck的方法。将父类变成一种属性,这个就是“有一个”属性。谁需要谁就用引进这个属性,
GreenHeadDuck:
public class GreenHeadDuck { private Duck duck; public GreenHeadDuck(Duck duck) { this.duck = duck; } public void display() { duck.display(); } }
这就是最简单的组合的例子。
也不是说组合一定比继承好,还是看具体会用情景。
还有其他组合的例子会在后续列举。