为什么Java不自动访问重写的方法?

Mar*_*eaș 2 java polymorphism

给定两个类,一个父类和一个子类:

class A {
    private void greet() {
        System.out.println("Class A");
    }
}

class B extends A {
    public void greet() {
        System.out.println("Class B");
    }
}
Run Code Online (Sandbox Code Playgroud)

一个有一个名为 的方法greet(),即private,另一个定义了一个同名的方法,只不过它是public。现在,据我所知,孩子的greet()方法不会覆盖父母的方法,因为它“隐藏”了它?(考虑到私有方法不能被重写?)

A现在,给出以下类和方法(被认为与和位于同一包中B):

public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.greet();
    }
}
Run Code Online (Sandbox Code Playgroud)

这应该可以编译。但这一个:

public class Main {
    public static void main(String[] args) {
        A a = new B();
        b.greet();
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的这个无法编译,因为它缺少类型转换。我的问题是:为什么?如果该greet()方法同时存在于两个地方,则两次public都会显示。Class B我很困惑为什么Java在运行时不计算,对于第二种情况,它a实际上引用了类型的对象B,并直接调用类中的方法B

尝试在 OCA 准备书中阅读更多有关多态性的内容,但作者似乎对此没有那么具体。

Era*_*ran 9

在无法编译的代码片段中,编译器会发现 的编译时类型a是 class A。因此,它只允许您调用类A(或 的超类A)的可访问方法。greetprivate的一种方法A,因此不可访问。因此编译器不允许调用它。

事实上, 的运行时类型a是 class B,它具有可访问的greet方法,这一事实没有什么区别,因为编译器不会尝试找出变量的运行时类型是什么。