Java方法重载+双重调度 [英] Java method overloading + double dispatch
问题描述
任何人都可以详细解释在使用 Child
时调用重载方法 print(父父级)
的原因在我的测试代码中的实例?
Can anybody explain in detail the reason the overloaded method print(Parent parent)
is invoked when working with Child
instance in my test piece of code?
这里涉及的Java中的任何虚拟方法或方法的重载/解决方案都是什么?
是否直接引用Java Lang Spec?
哪个术语描述了这种行为?
非常感谢。
Any pecularities of virtual methods or methods overloading/resolution in Java involved here? Any direct reference to Java Lang Spec? Which term describes this behaviour? Thanks a lot.
public class InheritancePlay {
public static class Parent {
public void doJob(Worker worker) {
System.out.println("this is " + this.getClass().getName());
worker.print(this);
}
}
public static class Child extends Parent {
}
public static class Worker {
public void print(Parent parent) {
System.out.println("Why this method resolution happens?");
}
public void print(Child child) {
System.out.println("This is not called");
}
}
public static void main(String[] args) {
Child child = new Child();
Worker worker = new Worker();
child.doJob(worker);
}
}
推荐答案
JLS在§8.4.9重载:
- 调用方法时(第15.12节),实际参数的数量(以及任何显式类型参数)和参数的编译时类型来确定将被调用的方法的签名(§15.12.2)。
- 如果要调用的方法是实例方法,将在运行时使用动态方法查找(第15.12.4节)确定要调用的实际方法。
- When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2).
- If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4).
所以在你的情况下:
- 方法参数(
this
)是编译时类型Parent
,因此调用方法print(Parent)
。 / li>
- 如果
Worker
类被子类化并且子类是wou ld重写该方法,并且worker
实例属于该子类,然后将调用重写的方法。
- The method argument (
this
) is of compile-time typeParent
, and so the methodprint(Parent)
is invoked. - If the
Worker
class was subclassed and the subclass would override that method, and theworker
instance was of that subclass, then the overridden method would be invoked.
Java中不存在双重调度。你必须模拟它,例如使用访客模式。在这种模式中,基本上,每个子类实现一个 accept
方法,并使用 this
作为参数调用访问者,并且这个
具有子类的编译时类型,因此使用了所需的方法重载。
Double dispatch does not exist in Java. You have to simulate it, e.g. by using the Visitor Pattern. In this pattern, basically, each subclass implements an accept
method and calls the visitor with this
as argument, and this
has as compile-time type that subclass, so the desired method overloading is used.
这篇关于Java方法重载+双重调度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!