polymorphism——可扩展性

来源:互联网 发布:图书编辑 知乎 编辑:程序博客网 时间:2024/06/13 02:59

现在,让我们回到“乐器”(instrument)示例。由于有多态机制,我们可根据自己的需求对系统添加任意多的新类型,而不需要更改tune()方法。在一个设计良好的oop程序中,大多数或者所有方法都会遵循tune()的模型,而且只与基类接口通信。这样的程序是可扩展性的,因为可以从通用的基类继承出新的数据类型,从而新添加一些功能。那么操作基类的接口的方法不需要任何改动就可以应用于新类。


考虑一下“乐器”的例子,如果我们向基类中添加了更多的方法,并加入一些新类,将会出现什么情况?请看下图:


这里写图片描述


事实上,不需要修改tune()方法,所有的新类都能与原有类一起正确运行。即使tune()方法是单独存放在某个文件中,并且在Instrument接口中添加了其他的方法,tune()方法也不要在编译就可以正确地运行。下面是具体的实现:

package polymorphism.music3;//:polymorphism/music3/Note.java//Notes to play on musical instruments.public enum Note {    MIDDLE_C,C_SHARP,B_FLAT;//ect}
package polymorphism.music3;//polymorphism/music3/Music3.java//An extensible programimport static net.mindview.util.Print.*;class Instrument {    public void play(Note n){        print("Instrument.play() "+n);    }    public String what(){        return "Instrument";    }    public void adjust(){        print("Adjusting Instrument");    }}class Wind extends Instrument{    public void play(Note n){        print("Wind.play() "+n);    }    public String what(){        return "Wind";    }    public void adjust(){        print("Adjusting Wind");    }}class Percussion extends Instrument{    public void play(Note n){        print("Percussion.play() "+n);    }    public String what(){        return "Percussion";    }    public void adjust(){        print("Adjusting percussion");    }}class Stringed extends Instrument{    public void play(Note n){        print("Stringed.play() "+n);                }    public String what(){        return "Stringed";    }    public void adjust(){        print("Adjusting Stringed");    }}class Brass extends Wind{    public void play(Note n){        print("Brass.play() "+n);    }    public void adjust(){        print("Adjusting Brass");    }}class Woodwind extends Wind{    public void play(Note n){        print("Woodwind.play() "+n);    }    public void adjust(){        print("Adjusting Woodwind");    }}public class Music3 {    //Don't care about tpye ,so new types     //added to the system still work right:    public static void tune(Instrument i){        //...        i.play(Note.MIDDLE_C);    }    public static void tuneAll(Instrument[] e){        for(Instrument i:e){            tune(i);        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        //Upcasting during addition to the array:        Instrument[] orchestra ={                new Wind(),                new Percussion(),                new Stringed(),                new Brass(),                new Woodwind()                      };        tuneAll(orchestra);         }}///:~输出结果:/* *  * Wind.play() MIDDLE_C * Percussion.play() MIDDLE_C * Stringed.play() MIDDLE_C * Brass.play() MIDDLE_C * Woodwind.play() MIDDLE_C *  */

分析:
新添加的方法what()返回一个带有类描述的String引用,另一个新添加的方法adjust()则提供每种乐器的调音方法。
在main()方法中,当我们将某种引用置入orchestra数组中,就会自动向上转型到Instrument。可以看到,tune()方法完全可忽略他周围代码所发生的全部变化,依旧正常运行。这正是我们期待多态所具有的特性。我们所做的代码修改,不会对程序中其他不应该受到影响的部分产生破坏。换句话说,多态是一项让程序员“将改变的事物与未变的事物分离开来”的重要技术。

0 0
原创粉丝点击