Java方法重载+双重调度

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (50)

任何人都可以详细解释在测试代码片段中print(Parent parent)处理Child实例时重载方法被调用的原因吗?

Java中涉及的任何虚拟方法或方法重载/解析的大小?任何直接参考Java Lang Spec?哪个术语描述了这种行为?非常感谢。

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节声明重载

  1. 当一个方法被调用时(§15.12),在编译时使用实际参数(以及任何显式类型参数)的数量和参数的编译时类型来确定将被调用的方法的签名( §15.12.2)。
  2. 如果要调用的方法是实例方法,则将使用动态方法查找(第15.12.4节)在运行时确定要调用的实际方法。

所以在你的情况下:

  1. 方法参数(this)是编译时类型的Parent,所以方法print(Parent)被调用。
  2. 如果Worker该类是子类,并且子类将覆盖该方法,并且该worker实例是该子类的,那么将调用重写的方法。

Java中不存在双重调度。你必须模拟它,例如通过使用访问者模式。在这种模式中,基本上,每个子类实现一个accept方法并this以参数的形式调用访问者,并且this具有子类的编译时类型,因此使用期望的方法重载。

用户回答回答于

原因是doJobParent和不在重载中实现Child。它传递this给工作人员的print方法,因为该方法将被调用this的类型。ParentWorker::print(Parent)

为了有Worker::print(Parent)叫你needto超载doJobChild

public static class Child extends Parent {
    public void doJob(Worker worker) {
        System.out.println("from Child: this is " + this.getClass().getName());

        worker.print(this);
    }
}

在上面的代码this.getClass()Child相当于Child.class

扫码关注云+社区

领取腾讯云代金券