这个程序看起来也许显得有些奇怪为什么所有人都应该有意忘记一个对象的类型呢?进行上溯造型时就可能产生这方面的疑惑而且如果让tune()简单地取得一个Wind句柄将其作为自己的自变量使用似乎会更加简单直观得多但要注意假如那样做就需为系统内Instrument的每种类型写一个全新的tune()假设按照前面的推论加入Stringed(弦乐)和Brass(铜管)这两种Instrument(乐器) //: Musicjava // Overloading instead of upcasting class Note { private int value; private Note(int val) { value = val; } public static final Note middleC = new Note() cSharp = new Note() cFlat = new Note(); } // Etc class Instrument { public void play(Note n) { Systemoutprintln(Instrumentplay()); } } class Wind extends Instrument { public void play(Note n) { Systemoutprintln(Windplay()); } } class Stringed extends Instrument { public void play(Note n) { Systemoutprintln(Stringedplay()); } } class Brass extends Instrument { public void play(Note n) { Systemoutprintln(Brassplay()); } } public class Music { public static void tune(Wind i) { iplay(NotemiddleC); } public static void tune(Stringed i) { iplay(NotemiddleC); } public static void tune(Brass i) { iplay(NotemiddleC); } public static void main(String[] args) { Wind flute = new Wind(); Stringed violin = new Stringed(); Brass frenchHorn = new Brass(); tune(flute); // No upcasting tune(violin); tune(frenchHorn); } } ///:~ 这样做当然行得通但却存在一个极大的弊端必须为每种新增的Instrument类编写与类紧密相关的方法这意味着第一次就要求多得多的编程量以后假如想添加一个象tune()那样的新方法或者为Instrument添加一个新类型仍然需要进行大量编码工作此外即使忘记对自己的某个方法进行过载设置编译器也不会提示任何错误这样一来类型的整个操作过程就显得极难管理有失控的危险 但假如只写一个方法将基础类作为自变量或参数使用而不是使用那些特定的衍生类岂不是会简单得多?也就是说如果我们能不顾衍生类只让自己的代码与基础类打交道那么省下的工作量将是难以估计的 这正是多形性大显身手的地方然而大多数程序员(特别是有程序化编程背景的)对于多形性的工作原理仍然显得有些生疏 |