FL0*_*0Nn 1 java double design-patterns concept dispatch
我正在尝试在JAVA中创建一个双重调度以使用重载方法。
public abstract class ComposantOrdi {
protected void equiv(ComposantOrdi c){
Equivalence.equiv(this, c);
}
}
public class Montage extends ComposantOrdi{
protected void equiv(Montage montage){
Equivalence.equiv(this, montage);
}
}
public class Equivalence {
public static void equiv(Montage m, ComposantOrdi c){
System.out.println("Montage - ComposantOrdi");
}
public static void equiv(Montage m, Montage c){
System.out.println("Montage - Montage");
}
public static void equiv(ComposantOrdi m, ComposantOrdi c){
System.out.println("ComposantOrdi - ComposantOrdi");
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个例子,我创建两个对象
Montage m2 = new Montage();
ComposantOrdi m3 = new Montage();
m3.equiv(m2);
m3.equiv(m3);
m3.equiv((Montage)m3);
Run Code Online (Sandbox Code Playgroud)
结果是:
ComposantOrdi - ComposantOrdi
ComposantOrdi - ComposantOrdi
ComposantOrdi - ComposantOrdi
Run Code Online (Sandbox Code Playgroud)
但是我想使用Montage类的重载方法,并得到这样的东西:
Montage - Montage
Montage - Montage
Montage - Montage
Run Code Online (Sandbox Code Playgroud)
我可能不理解双重派遣,但是请您告诉我我做错了什么吗?
您在代码中执行的操作是单次调度(而不是双重调度-下文解释),因为在运行时仅评估一种具体的子类型会影响结果(对象本身将传递为this)。
另外ComposantOrdi,Montage提供不同的方法(检查参数:ComposantOrdigets ComposantOrdiwhile Montagegets Montage)。如果调用超类的equiv方法,则无法获得像Montage-Montage这样的结果,因为每个传递的内容Montage都隐式转换为ComposantOrdi。像这种调用超类的方法一样,结果的第二部分不能是ComposantOrdi。
此外,如果你调用父类的方法关键字this中
Equivalence.equiv(this,c);
由超类触发,这意味着即使对象是a,Montage它也将自身传递为ComposantOrdi。
因此:调用超类的方法只能产生输出ComposantOrdi-ComposantOrdi。
对于像Montage-Montage这样的输出,您需要调用子类的方法equiv,这意味着:
equiv呼叫的接收者引用为Montage(参见m2,而不是m3)Montage对象因为这样关键字在输出的第一部分this被触发Montage必须是Montage。第二部分也是Montage,因为Java在不需要时不会隐式转换对象。这就是为什么Montages选择以as作为参数的重载方法的原因。
因此:调用子类的方法只能产生输出Montage-Montage。
equiv永远不会调用等价方法的混合版本。
说明双重分配机制:
我认为双重派遣机制存在根本性的误解。因此,让我解释一下。在继续介绍双调度机制之前,我将开始解释单调度。
单一调度:单一调度表示您调用对象的方法,并且已执行的行为(方法调用的结果)取决于对象的具体类型。通常,这称为多态性,是使用抽象方法或方法重写实现的。
假设您根据下图有一个班级系统。将Client持有的名单Shapes。要绘制所有内容,它遍历列表并调用paint每个 列表Shape。当班级Triangle在屏幕上绘制一个三角形时,则Square绘制一个正方形。通过不考虑具体的子类型,Shapes可以在运行时确定执行的行为。
换句话说,paint方法的调用结果取决于Shape接口派生类的具体子类型。由于只有一个具体的子类型可以确定运行时所执行的行为,所以paint方法的调用是单个调度。
双重调度:使用双重调度机制,执行的行为在运行时受到两种具体子类型的影响。像这样,您将跨越一个行为矩阵,并对其进行动态评估。
如果您根据下面的图片修改类系统,则客户端触发的绘制机制取决于两个对象- Shape和一个Painter。客户端调用该paint方法并注入Painter。然后,Shape传递本身就像this的重载方法之一一样Painter。
这样就Client触发了绘制机制,而又不知道以哪种颜色绘制哪种形状。例如,如果其画家为a GreenPainter且Shape为a,Triangle则屏幕上会出现一个绿色三角形。
在此示例中,双重分配机制是通过调用Shapes' paint方法触发的。
您应该看看使用双重分配机制的访客模式。
| 归档时间: |
|
| 查看次数: |
569 次 |
| 最近记录: |