由于java的动态绑定只能处理一个类型,所以如果要执行的操作包含不止一个类型未知的对象时,就需要使用多路分发.其中多路分发使用了多态机制,所以只能发生在方法调用时.以石头,剪刀,布的例子说明
1 使用enum分发
定义返回结果:
package enumeration; public enum Outcome { WIN,LOSE,DRAW }
使用构造器来初始化每个enum实例
package enumeration; import static enumeration.Outcome.*; public enum RoShamBo { //初始化 PAPER(DRAW, LOSE, WIN), SCISSORS(WIN, DRAW, LOSE), ROCK(LOSE, WIN, DRAW); private Outcome vPAPER, vSCISSORS, vROCK; RoShamBo(Outcome paper, Outcome scissors, Outcome rock) { this.vPAPER = paper; this.vSCISSORS = scissors; this.vROCK = rock; }
public Outcome compete(RoShamBo it) { switch (it) { default: case PAPER: return vPAPER; case SCISSORS: return vSCISSORS; case ROCK: return vROCK; } } }
这个简单例子中用3个枚举实例,每个枚举实例又包含3个结果,构建了一个3*3的二维表.
取得的效果是:只有第一次分发是实际调用,第二次分发使用的是switch
2 使用二维数组
package enumeration; import static enumeration.Outcome.*; public enum RoShamBo2 { PAPER, SCISSORS, ROCK; //结果表 private static Outcome[][] table = { { DRAW, LOSE, WIN }, // PAPER { WIN, DRAW, LOSE }, // SCISSORS { LOSE, WIN, DRAW },// ROCK }; public Outcome compete(RoShamBo2 other) { return table[this.ordinal()][other.ordinal()]; } }
这种方法直接构建一个二维数组按规定好的顺序储存结果
取得的效果是:只有第一次分发仍是实际调用,第二次分发却使用的更简便的数组索引,表达力强大,代码简短