Java方法重载+;双重派遣
有人能详细解释在我的测试代码中使用Java方法重载+;双重派遣,java,oop,overloading,double-dispatch,Java,Oop,Overloading,Double Dispatch,有人能详细解释在我的测试代码中使用Child实例时调用重载方法print(Parent-Parent)的原因吗 这里涉及到Java中虚拟方法或方法重载/解析的特殊性吗? 有没有直接引用Java语言规范? 哪个术语描述这种行为? 非常感谢 public class InheritancePlay { public static class Parent { public void doJob(Worker worker) { Sys
Child
实例时调用重载方法print(Parent-Parent)
的原因吗
这里涉及到Java中虚拟方法或方法重载/解析的特殊性吗?
有没有直接引用Java语言规范?
哪个术语描述这种行为?
非常感谢
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);
}
}
原因是
doJob
在Parent
中实现,而不是在Child
中重载。它将this
传递给工作者的print
方法,因为this
属于Parent
类型,将调用方法worker::print(Parent)
要调用Worker::print(Parent)
,您需要在子项中重载doJob
:
public static class Child extends Parent {
public void doJob(Worker worker) {
System.out.println("from Child: this is " + this.getClass().getName());
worker.print(this);
}
}
在上面的代码中,Child
中的这个.getClass()
相当于Child.class
中的JLS状态:
this
)属于编译时类型Parent
,因此调用方法print(Parent)
Worker
类是子类,子类将重写该方法,并且Worker
实例是该子类的实例,则将调用被重写的方法Java中不存在双重分派。您必须模拟它,例如使用。在这个模式中,基本上,每个子类都实现了一个
accept
方法,并使用this
作为参数调用访问者,this
作为该子类的编译时类型,因此使用了所需的方法重载。rsp,感谢您指出这一点,但我知道在Child中重写doJob会使prog工作。问题是我不明白为什么:)。让我们看一下最初的代码。当我们将子对象传递给Parent.doJob时,Parent.doJob中的Java反射证明我们处理的是这种类型的Child,那么为什么重载方法的解析会失败呢?@Max,在方法中,this
的类型始终是方法所在的类的类型。编译器无法知道该类将来将被继承,它必须使用它当时拥有的知识this.getClass()
是运行时信息,而不是编译时信息。Christian,谢谢你详尽的回答!所以我们在这里讨论运行时和编译时类型的问题。我将深入探讨这个话题。(这里提到双重分派是因为我在学习访问者模式时遇到了这个问题:))。马克斯