polymorphism——可扩展性

现在,让我们回到“乐器”(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 program

import 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()方法完全可忽略他周围代码所发生的全部变化,依旧正常运行。这正是我们期待多态所具有的特性。我们所做的代码修改,不会对程序中其他不应该受到影响的部分产生破坏。换句话说,多态是一项让程序员“将改变的事物与未变的事物分离开来”的重要技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值