多路分发

 多路分发

 

Number.plus(Number)

 

Number是各种数字对象的超类。 当声明a.plus(b)时,并不知道a,b的确切类型。

如何正确地交互?

Java只支持单路分发,如果要执行的操作包含了不止一个类型未知的对象时,

那么Java的动态绑定机制只能处理其中一个的类型。所以必须自己来判定其他的

类型,从而实现自己的动态绑定行为。

 

解决的办法就是多路分发,如果想使用2路分发,那么必须有2个方法调用,

第一个方法调用决定第一个未知类型,第二个方法调用决定第二个未知类型。

所以必须为每一个类型提供给一个实际的方法调用

 

一般而言,需要有设定好的某种配置,以便一个方法调用能够引出更多的方法

调用,从而能够在这个过程中处理多种类型。

 

为了达到这种效果,我们需要与多个方法一同工作: 因为每个分发都需要一个

方法调用。

 

下面剪刀 石头 布 游戏对应的方法是compete()和eval(),二者都是同一个类型

的成员, 可以产生三种Outcome实例中的一个作为结果。



public enum Outcome {
		WIN, LOSE, DRAW
	}

	import java.util.Random;
import static enumerated.Outcome.*;


interface Item{
	Outcome compete(Item it);
	Outcome eval(Paper p);
	Outcome eval(Scissors s);
	Outcome eval(Rock r);
}

class Paper implements Item{
	public Outcome compete(Item it) {
		return it.eval(this);
	}
	public Outcome eval(Paper p) {
		return DRAW;
	}
	public Outcome eval(Scissors s) {
		return WIN;
	}
	public Outcome eval(Rock r) {
		return LOSE;
	}
	public String toString(){
		return "Paper";
	}
}

class Scissors implements Item{
	public Outcome compete(Item it) {
		return it.eval(this);
	}
	public Outcome eval(Paper p) {
		return LOSE;
	}
	public Outcome eval(Scissors s) {
		return DRAW;
	}
	public Outcome eval(Rock r) {
		return WIN;
	}
	public String toString(){
		return "Scissors";
	}
}

class Rock implements Item{
	public Outcome compete(Item it) {
		return it.eval(this);
	}
	public Outcome eval(Paper p) {
		return WIN;
	}
	public Outcome eval(Scissors s) {
		return LOSE;
	}
	public Outcome eval(Rock r) {
		return DRAW;
	}
	public String toString(){
		return "Rock";
	}
}
public class RoShamBol {
	static final int SIZE = 20;
	private static Random rand = new Random(47);
	public static Item newItem(){
		switch(rand.nextInt(3)){
		default:
		case 0 : return new Scissors();
		case 1 : return new Paper();
		case 2 : return new Rock();
		}
	}
	
	public static void match(Item a, Item b){
		System.out.println(a +" vs. "+ b+" : "+ a.compete(b));
	}
	public static void main(String[] args) {
		for(int i=0; i<SIZE; i++)
			match(newItem(), newItem());
	}
}
 
 Item是这几种类型的接口, 用作多路分发。 RoshamBol.match()有2个item参数,
 通关过Item.compete()方法开始2路分发,要判定a的类型,分发机制会在a的实际
 类型的compete()内部起到分发作用。compete()方法通关过eval()来为另一个类型
 实现第二次分发, 将自身(this)作为参数调用eval(),能够调用重载过的eval()
 方法,这能够保留第一次分发的类型信息,第二次分发完成时,就能知道两个Item
 对象的具体类型了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值