现在我们有一个虚基类-鸭子(abstract Duck). 有真鸭子,野鸭子,橡皮鸭子继承了该类。虚基类有swing方法,毕竟游泳是所有的鸭子都应有的功能。还有一个虚方法display,这个方法在子类中复写,毕竟每种鸭子的信息不一样。
现在我们有新的需求,需要让我们的鸭子会飞。那么我们可以轻松的想到,在Duck虚基类中增加一个fly方法就行了。但实际上,如果真这么做的话,会让所有的鸭子都有该功能。而实际上,橡皮鸭是不能飞的!那么,干脆我们不把fly方法写到基类,而是把fly方法抽象成接口,让需要该功能的类都实现这个接口。这样也会有问题,假如我们有更多种类的鸭子怎么办?我们是不是要为每一个新增的鸭子子类都实现这个接口呢?这样无疑给我们代码增加了很多维护成本,也降低了扩展性。
好的,是时候揭晓答案了。我们抽象出一个FlyBehavior接口,然后将各种飞行的方法抽象成不同的类,让不同的类都实现FlyBehavior借口。然后在我们的Duck虚基类中设置一个FlyBehavior属性,让鸭子具有这种功能。当我们在写子类的时候我们可以动态的决定该子类需要什么样的Fly方法。
代码如下:
FlyBehavior接口:
public interface FlyBehavior { void fly(); }
FlyWithWing子类实现FlyBehavior接口。该类代表正常的飞行能力。
public class FlyWithWing implements FlyBehavior { public void fly() { // TODO Auto-generated method stub System.out.println("Fly with wing...."); } }
FlyNoWay子类实现FlyBehavior接口。该类代表没有飞行能力。
public class FlyNoWay implements FlyBehavior { public void fly() { // TODO Auto-generated method stub System.out.println("Cannot fly."); //throw new Exception("can not fly"); } }
FlyWithRocketPower实现FlyBehavior接口。该类代表鸭子装上了火箭引擎的飞行能力。
public class FlyWithRocketPower implements FlyBehavior { public void fly() { // TODO Auto-generated method stub System.out.println("Fly with a rocket power on"); } }
Duck虚基类:
public abstract class Duck { private FlyBehavior flyBehavior; public Duck() {} public void fly() { this.flyBehavior.fly(); } public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void swing() { System.out.println("duck is swinging"); } public abstract void display(); }
RealDuck类,继承了Duck类。真实的鸭子用翅膀飞。
public class RealDuck extends Duck { public RealDuck() { super.setFlyBehavior(new FlyWithWing()); } @Override public void display() { // TODO Auto-generated method stub System.out.println("This is a real duck"); } }
RubberDuck类,继承了Duck类。橡皮鸭不能飞。
public class RubberDuck extends Duck { public RubberDuck() { super.setFlyBehavior(new FlyNoWay()); } @Override public void display() { // TODO Auto-generated method stub System.out.println("This is a rubber duck. it cannot fly nor quack."); } }
SupperDuck类,继承了Duck类。超级鸭子能用火箭做动力。
public class SuperDuck extends Duck { public SuperDuck() { super.setFlyBehavior(new FlyWithRocketPower()); } @Override public void display() { // TODO Auto-generated method stub System.out.println("This is a super duck. It can fly with rocket power to the moon."); } }
main函数,测试方法。实例化各种子类,然后还可以动态设置各个鸭子具有的功能。本例中,橡皮鸭一开始不能飞,但后来将其升级为用火箭做动力的鸭子。
public class DuckSimulator { public static void main(String[] args) { Duck realDuck = new RealDuck(); realDuck.fly(); realDuck.display(); System.out.println("============================"); RubberDuck rubberDuck = new RubberDuck(); rubberDuck.fly(); rubberDuck.display(); System.out.println("============================"); SuperDuck superDuck = new SuperDuck(); superDuck.fly(); superDuck.display(); System.out.println("============================"); //upgrade rubber duck to rocket power rubberDuck.setFlyBehavior(new FlyWithRocketPower()); rubberDuck.fly(); } }
输出结果如下:
Fly with wing....
This is a real duck
============================
Cannot fly.
This is a rubber duck. it cannot fly nor quack.
============================
Fly with a rocket power on
This is a super duck. It can fly with rocket power to the moon.
============================
Fly with a rocket power on