java 多路分发_java实现多路分发

多路分发就是指在调用a.plus(b),a和b都不知道确切类型,也能让他们正常交互。

如果想使用两路分发,那么必须有两个方法调用,第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型。要利用多路分发,程序员必须为每一个类型提供给一个实际的方法调用。一般而言,程序员需要设定好某种配置,以便一个方法调用能够引出更多的方法调用,从而能在这个过程中处理多个类型。

下面是个“石头 剪刀 布”(RoShamBo)游戏的例子 (from: thinking in java):

publicenumOutcome { WIN, LOSE, DRAW }///枚举类型:赢,输,平局

interfaceItem {

Outcome compete(Item it);

Outcome eval(Paper p);

Outcome eval(Scissors s);

Outcome eval(Rock r);

}

classPaperimplementsItem {

publicOutcome compete(Item it) {

returnit.eval(this);

}

publicOutcome eval(Paper p) {

returnDRAW;

}

publicOutcome eval(Scissors s) {

returnWIN;

}

publicOutcome eval(Rock r) {

returnLOSE;

}

publicString toString() {

return"Paper";

}

}

classScissorsimplementsItem {

publicOutcome compete(Item it) {

returnit.eval(this);

}

publicOutcome eval(Paper p) {

returnLOSE;

}

publicOutcome eval(Scissors s) {

returnDRAW;

}

publicOutcome eval(Rock r) {

returnWIN;

}

publicString toString() {

return"Scissors";

}

}

classRockimplementsItem {

publicOutcome compete(Item it) {

returnit.eval(this);

}

publicOutcome eval(Paper p) {

returnWIN;

}

publicOutcome eval(Scissors s) {

returnLOSE;

}

publicOutcome eval(Rock r) {

returnDRAW;

}

publicString toString() {

return"Rock";

}

}

publicclassRoShamBo1 {

staticfinalintSIZE =20;

privatestaticRandom rand =newRandom(47);

publicstaticItem newItem(){

switch(rand.nextInt(3)) {

default:

case0:

returnnewScissors();

case1:

returnnewPaper();

case2:

returnnewRock();

}

}

publicstaticvoidmatch(Item a, Item b) {

System.out.println(a + " vs. "+ b +": "+a.compete(b));

}

publicstaticvoidmain(String[] args) {

for(inti =0; i 

match(newItem(), newItem());

}

}

RoshamBol.match()有2个item参数,通关过Item.compete()方法开始2路分发,要判定a的类型,分发机制会在a的实际类型的compete()内部起到分发作用。compete()方法通关过eval()来为另一个类型实现第二次分发, 将自身(this)作为参数调用eval(),能够调用重载过的eval()方法,这能够保留第一次分发的类型信息,第二次分发完成时,就能知道两个Item对象的具体类型了。

因此,试着执行一下上述的main函数,match(newItem(),newItem())中的两个参数是生成的两个随机的对象,假设某次随机的 match(newItem(), newItem()) 为match(paper,scissor)。那么调用paper.compete(scissor),又paper.compete(scissor){ return scissor.eval(paper)},故而调用Scissor对象的eval(Paper paper)方法,返回Lose。因此main函数最终输出的结果是" paper vs scissor: Lose "。

用上述方法,就能避免 if else的书写和获取对象具体类型的方法

这种方法的精妙之处在于,通过调用 item1的compete方法,实现对item1的类型的分发,而在item1的compete方法中,用通过调用item2的eval方法,将自身this昨晚参数,实现了Item2中eval方法的分发

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值