上个学期老师就推荐了《Head.First设计模式》这本书,一直没有时间去看。从今天开始,终于有时间来仔细看了……今天看到的有两个设计原则,下面简单理解一下多态在实际问题中的应用。
按照这本书的例子和写作风格,我的笔记也这样记录下来。本书用一个制作鸭子的类进行引入:
公司制作的一个游戏中,定义了一个Duck类。
这天,公司为了升级游戏,决定在展示给客户的时候能让鸭子飞起来。按照OO设计思想,只要将fly()方法加入到Duck类中,其他的鸭子的子类,就都可以进行继承了,很不错的想法!于是,大家就这样做了。事后发现,这简直是个糊涂的决定,因为,如果我们派生出一个橡皮鸭,难道也要在天上飞来飞去吗?!肯定不行。
以上是基本的背景介绍。
一、找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码混在一起。
也就是说,在设计之前,将可能变化的部分与不需要变化的部分分开来实现,以鸭子这个类为例的话,fly()方法就要分出来。
这个原则涉及到了每个编程过程。
二、针对接口编程,而不是针对实现编程
这一点,从本质上解决了本实例中出现的问题,其中主要涉及到的内容是多态。
首先,我们先看一下下面两个代码的区别:
1、面向实现编程:
- //面向实现编程
- Dog d = new Dog();
- d.bark();
2、面向接口编程:
- //面向接口编程
- Animal animal = new Dog();
- animal.bark();
同样,这里的例子也是一样:首先,我们肯定已经将鸭子飞的动作与Duck类分开来实现。那么,我们要想为了实现代码的重用,想到了可爱的多态,实现方法如下:
1、定义一个接口,写入鸭子飞的方法:
- public interface FlyBehavior{
- public void fly();
- }
2、两种飞的结果,一个是会飞,一个是不会飞,也就用两个类进行相应的实现:
- //会飞的鸭子可以继承这个类
- public class FlyClass implements FlyBehavior{
- public void fly(){
- System.out.print("This class can fly!");
- }
- }
- //不会飞的继承这个类
- public class NoFlyClass implements FlyBehavior{
- public void fly(){
- System.out.print("This class can not fly!");
- }
- }
3、将之前的Duck类加到一起实现上述功能:
Duck.java实现过程:
- public class Duck{
- FlyBehavior flybehavior ;
- public void flyperform(){
- flybehavior.fly();
- }
- //其他属性和方法
- }
定义可以飞的,FlyDuck.java实现过程:
- public class FlyDuck extends Duck{
- public FlyDuck(){
- flybehavior = new FlyClass();
- }
- public static void main(String args[]){
- FlyDuck flyduck = new FlyDuck();
- flyduck.flyperform();
- }
- }
输出结果为:This class can fly!
也可以定义不可以飞的NoFlyDuck.java:
- public class NoFlyDuck extends Duck{
- public NoFlyDuck(){
- flybehavior = new NoFlyClass();
- }
- public static void main(String args[]){
- NoFlyDuck noflyduck = new NoFlyDuck();
- noflyduck.flyperform();
- }
- }
输出结果:This class can not fly!
三、总结
利用接口实现了多态,而且,可以根据需要,将实现接口的类进行修改就可以全部改变子类鸭子的动作。