按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
import c16。trash。*;
public class DDCardboard extends Cardboard
implements TypedBinMember {
public DDCardboard(double wt) { super(wt); }
public boolean addToBin(TypedBin'' tb) {
for(int i = 0; i 《 tb。length; i++)
if(tb'i'。add(this))
return true;
return false;
}
} ///:~
每个addToBin()内的代码会为数组中的每个TypeBin 对象调用add()。但请注意参数:this。对Trash 的每
个子类来说,this 的类型都是不同的,所以不能认为代码“完全”一样——尽管以后在 Java 里加入参数化
类型机制后便可认为一样。这是双重派遣的第一个部分,因为一旦进入这个方法内部,便可知道到底是
Aluminum ,Paper,还是其他什么垃圾类型。在对add()的调用过程中,这种信息是通过this 的类型传递
的。编译器会分析出对 add()正确的过载版本的调用。但由于tb'i'会产生指向基础类型 TypeBin 的一个句
柄,所以最终会调用一个不同的方法——具体什么方法取决于当前选择的 TypeBin 的类型。那就是第二次派
遣。
下面是TypeBin 的基础类:
//: TypedBin。java
// Vector that knows how to grab the right type
package c16。doubledispatch;
import c16。trash。*;
import java。util。*;
public abstract class TypedBin {
Vector v = new Vector();
protected boolean addIt(Trash t) {
v。addElement(t);
return true;
}
public Enumeration elements() {
return v。elements();
}
public boolean add(DDAluminum a) {
return false;
609
…………………………………………………………Page 611……………………………………………………………
}
public boolean add(DDPaper a) {
return false;
}
public boolean add(DDGlass a) {
return false;
}
public boolean add(DDCardboard a) {
return false;
}
} ///:~
可以看到,过载的 add()方法全都会返回false。如果未在衍生类里对方法进行过载,它就会一直返回
false,而且调用者(目前是 addToBin())会认为当前Trash 对象尚未成功加入一个集合,所以会继续查找
正确的集合。
在TypeBin 的每一个子类中,都只有一个过载的方法会被过载——具体取决于准备创建的是什么垃圾筒类
型。举个例子来说,CardboardBin 会过载 add(DDCardboard)。过载的方法会将垃圾对象加入它的集合,并返
回true。而CardboardBin 中剩余的所有add()方法都会继续返回 false,因为它们尚未过载。事实上,假如
在这里采用了参数化类型机制,Java 代码的自动创建就要方便得多(使用 C++的“模板”,我们不必费事地
为子类编码,或者将addToBin()方法置入Trash 里;Java 在这方面尚有待改进)。
由于对这个例子来说,垃圾的类型已经定制并置入一个不同的目录,所以需要用一个不同的垃圾数据文件令
其运转起来。下面是一个示范性的 DDTrash。dat:
c16。DoubleDispatch。DDGlass:54
c16。DoubleDispatch。DDPaper:22
c16。DoubleDispatch。DDPaper:11
c16。DoubleDispatch。DDGlass:17
c16。DoubleDispatch。DDAluminum:89
c16。DoubleDispatch。DDPaper:88
c16。DoubleDispatch。DDAluminum:76
c16。DoubleDispatch。DDCardboard:96
c16。DoubleDispatch。DDAluminum:25
c16。DoubleDispatch。DDAluminum:34
c16。DoubleDispatch。DDGlass:11
c16。DoubleDispatch。DDGlass:68
c16。DoubleDispatch。DDGlass:43
c16。DoubleDispatch。DDAluminum:27
c16。DoubleDispatch。DDCardboard:44
c16。DoubleDispatch。DDAluminum:18
c16。DoubleDispatch。DDPaper:91
c16。DoubleDispatch。DDGlass:63
c16。DoubleDispatch。DDGlass:50
c16。DoubleDispatch。DDGlass:80
c16。DoubleDispatch。DDAluminum:81
c16。DoubleDispatch。DDCardboard:12
c16。DoubleDispatch。DDGlass:12
c16。DoubleDispatch。DDGlass:54
c16。DoubleDispatch。DDAluminum:36
c16。DoubleDispatch。DDAluminum:93
c16。DoubleDispatch。DDGlass:93
c16。DoubleDispatch。DDPaper:80
c16。DoubleDispatch。DDGlass:36
610
…………………………………………………………Page 612……………………………………………………………
c16。DoubleDispatch。DDGlass:12
c16。DoubleDispatch。DDGlass:60
c16。DoubleDispatch。DDPaper:66
c16。DoubleDispatch。DDAluminum:36
c16。DoubleDispatch。DDCardboard:22
下面列出程序剩余的部分:
//: DoubleDispatch。java
// Using multiple dispatching to handle more
// than one unknown type during a method call。
package c16。doubledispatch;
import c16。trash。*;
import java。util。*;
class AluminumBin extends TypedBin {
public boolean add(DDAluminum a) {
return addIt(a);
}
}
class PaperBin extends TypedBin {
public boolean add(DDPaper a) {
return addIt(a);
}
}
class GlassBin extends TypedBin {
public boolean add(DDGlass a) {
return addIt(a);
}
}
class CardboardBin extends TypedBin {
public boolean add(DDCardboard a) {
return addIt(a);
}
}
class TrashBinSet {
private TypedBin'' binSet = {
new AluminumBin();
new PaperBin();
new GlassBin();
new CardboardBin()
};
public void sortIntoBins(Vector bin) {
Enumeration e = bin。elements();
while(e。hasMoreElements()) {
TypedBinMember t =
(TypedBinMember)e。nextElement();
if(!t。addToBin(binSet))
611
…………………………………………………………Page 613……………………………………………………………
System。err。println(〃Couldn't add 〃 + t);
}
}
public TypedBin'' binSet() { return binSet; }
}
public class DoubleDispatch {
public static void main(String'' args) {
Vector bin = new Vector();
TrashBinSet bins = new TrashBinSet();
// ParseTrash still works; without changes:
ParseTrash。fillBin(〃DDTrash。dat〃; bin);
// Sort from the master bin into the
// individually…typed bins:
bins。sortIntoBins(bin);
TypedBin'' tb = bins。binSet();
// Perform sumValue for each bin。。。
for(int i = 0; i 《 tb。length; i++)
Trash。sumValue(tb 'i'。v);
// 。。。 and for the master bin
Trash。sumValue(bin);