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

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

class B extends A {
    public void greet() {
        System.out.println("Class B");
    }
}

一个有一个名为greet()的方法,它是private,另一个定义了一个同名的方法,只是它是public.现在,据我所知,子方法的greet()没有覆盖父方法,因为它‘隐藏’了它?(鉴于私有方法不能被覆盖的事实?)

现在,给定以下类和方法(被认为与AB在同一个包中):

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

这应该会编译.但这一次:

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

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

我试着在一本准备OCA的书中阅读更多关于多态的内容,但作者似乎对此并不那么具体.

推荐答案

在不编译的代码片段中,编译器看到a的编译时类型是类A. 因此,它只允许调用类A(或A的超类)的可访问方法.greetAprivate方法,因此无法访问.因此,编译器不允许调用它.

a的运行时类型是类B,它有一个可访问的greet方法,这一事实没有什么不同,因为编译器不会try 计算变量的运行时类型.

Java相关问答推荐

为什么我要创建一个单独的互斥体/锁对象?

Java记录的不同序列化/反序列化

在bash中将数组作为Java程序的参数传递

Helidon 4和Http API

如何对多个字段进行分组和排序?

Domino Designer 14中的保存代理添加了重影库

没有使用Lombok生成的参数

Lombok@Nonnull是否也对供应商有影响?

如何配置空手道以使用FeignClient或RestTemplate代替ApacheHttpClient

FETCH类型设置为LAZY,但它仍会发送第二个请求

try 在两个不同数组的数字之间求平均值

插入中的JOOQ序列,设置为VS值

如何通过Java java.lang.Foreign API访问本机字节数组

Maven-Dependency-Plugin 3.6.+开始查找在依赖关系:分析目标期间找到的新的使用的未声明依赖关系

为什么创建Java动态代理需要接口参数

从字节数组切换到JakartaMail org.springframework.mail.javamail.JavaMailSender InputStreamResource

在JSON上获取反斜杠

带有提取器的JavaFXObservableList会根据侦听器的存在而改变行为

从 Java 17 切换回 Java 8 后出现的问题

为什么当我输入变量而不是直接输入字符串时,我的方法不起作用?