java包围与过载
此刻让我们用差异的目光来看看本章的头一个例子。在下面这个措施中,要领play()的接口会在被包围的进程中产生变革。这意味着我们实际并没有“包围”要领,而是使其“过载”。编译器答允我们对要领举办过载处理惩罚,使其不陈诉堕落。但这种行为大概并不是我们所但愿的。下面是这个例子:
//: WindError.java // Accidentally changing the interface class NoteX { public static final int MIDDLE_C = 0, C_SHARP = 1, C_FLAT = 2; } class InstrumentX { public void play(int NoteX) { System.out.println("InstrumentX.play()"); } } class WindX extends InstrumentX { // OOPS! Changes the method interface: public void play(NoteX n) { System.out.println("WindX.play(NoteX n)"); } } public class WindError { public static void tune(InstrumentX i) { // ... i.play(NoteX.MIDDLE_C); } public static void main(String[] args) { WindX flute = new WindX(); tune(flute); // Not the desired behavior! } } ///:~
这里还向各人引入了另一个易于夹杂的观念。在InstrumentX中,play()要领回收了一个int(整数)数值,它的标识符是NoteX。也就是说,纵然NoteX是一个类名,也可以把它作为一个标识符利用,编译器不会陈诉堕落。但在WindX中,play()回收一个NoteX句柄,它有一个标识符n。即便我们利用“play(NoteX NoteX)”,编译器也不会陈诉错误。这样一来,看起来就象是措施员有意包围play()的成果,但对要领的范例界说却稍微有些不确切。然而,编译器此时假定的是措施员有意举办“过载”,而非“包围”。请仔细体会这两个术语的区别。“过载”是指同一样对象在差异的处所具有多种寄义;而“包围”是指它随时随地都只有一种寄义,只是原先的寄义完全被厥后的寄义代替了。请留意假如遵守尺度的Java定名类型,自变量标识符就应该是noteX,这样可把它与类名区分隔。
在tune中,“InstrumentX i”会发出play()动静,同时将某个NoteX成员作为自变量利用(MIDDLE_C)。由于NoteX包括了int界说,过载的play()要领的int版本会获得挪用。同时由于它尚未被“包围”,所以会利用基本类版本。
输出是:
InstrumentX.play()