0

起初我是一个初学者
,我看了很多教程,阅读了很多例子,甚至从 JLS 都试图理解这个主题,但我仍然有一些困惑或误解。

让我告诉你我无法理解的问题。

假设我们有三个类Parent, Child1Child2如下所示:

class Parent {
    void doSmth(Object o) {
        System.out.println("Parent.doSmth");
    }
}

class Child1 extends Parent {
    void doSmth(Object o) {
        System.out.println("Child1.doSmth");
    }
}

class Child2 extends Parent {
    void doSmth(String s) {
        System.out.println("Child2.doSmth");
    }
}

class Test {
    public static void main(String[] args) {
        Parent p1 = new Child1();
        Parent p2 = new Child2();

        p1.doSmth("String");
        p2.doSmth("String");
    }
}

我的理解是,因为 和 的引用p1来自p2type Parent,所以doSmth(Object)只有编译器才能看到。

因为p1.doSmth("String");编译器没有绑定它,因为有一个覆盖方法,所以它只是让JVM在运行时绑定它(动态绑定)。

p2.doSmth("String");编译器绑定它,因为它没有找到覆盖它的方法(静态绑定)。

问题是,我说的是真的吗?还是我有误解?如果它是错误的,那么请告诉我在这种情况下编译器会采取哪些步骤?
如果它是真的,编译器怎么能期望p1.doSmth它有一个覆盖方法(虽然它不知道它是真正的类型),而p2.doSmth它只是绑定它?我错过了什么吗?

对不起,但这真的让我头疼..

4

1 回答 1

2

试图总结讨论。根据需要进行编辑。

Java 中的静态绑定发生在编译时,而动态绑定发生在运行时。

在编译时,p1 和 p2 都是 Parent 的类型,并且 Parent 具有 doSmth(Object) 方法,因此这两行都绑定到同一个方法。

    p1.doSmth("String");
    p2.doSmth("String");

在运行时,动态绑定就出现了。

p1 是 Child1 的实例,并且 Child1 已覆盖 doSmth(Object) 因此使用来自 Child1 的实现。

p2 是 Child2 的实例,并且 Child2 不会覆盖 doSmth(Object) 因此调用从 Parent 继承的方法的实现。

于 2018-01-04T01:02:48.760 回答