我遇到以下四个类的问题:
class X {
void a() {
b();
c();
}
void b() {
System.out.println("b from class X");
}
private void c() {
System.out.println("c from class X");
}
}
class Y extends X {
void b() {
System.out.println("b from class Y");
}
}
class Z extends Y {
void b() {
System.out.println("b from class Z");
}
void c() {
System.out.println("c from class Z");
}
}
public class Main {
public static void main(String[] args) {
Y y = new Z();
y.a();
}
}
请不要评论类(class)的合理性,这只是一个例子。我还尝试通过使用 Eclipse 调试器的方法来跟踪 JVM 的流程,但这些方法的步骤在某些时候有点快。
我已经知道了
Y y = new Z();
创建 Z 类的新实例并将其分配给 Y 类的引用。由于Z中没有构造函数,编译器会在每个父类(super class)中查找是否有构造函数,如果没有,则使用对象类的构造函数。 之后
y.a();
方法被调用。类 Z 中没有这样的方法,因此我们再次到达存在方法 a 的类 X 并执行它。 首先我们执行方法b,因为你的对象是类Z的实例,并且方法b在类Z中被覆盖,导致输出
b from class Z.
之后调用方法c(在方法a中)。由于我们的实例仍然是类 Z 的实例,并且该类中存在方法 c,因此您可能会想到输出
c from class Z
将会发生。但这不是真的,因为类 X 中的 c 方法是私有(private)方法。由于它是私有(private)的,因此不能继承到子类(甚至看不到)。因此,任何从 X 继承的类都不需要具有 c 方法。是不是因为从方法 a 调用 c 导致调用类 X 中的 c 方法而不是类 Z 中的 c 方法?
所以回顾一下: 我上面的解释正确还是我遗漏了什么?我只是有点困惑,虽然我的实例来自类 Z,但从方法 a 内部调用方法 c 会导致以下结果:
b from class Z
c from class X
我的第一个想法是输出如下:
b from class Z
c from class Z
希望我以现在有人可以帮助我的方式描述了这个问题。谢谢大家的回复。
最佳答案
确实会打印以下内容:
c from class X
因为c
在X
中是私有(private)
,并且private methods aren't inherited in Java 。
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
所以,即使X
的方法a
调用了c
方法,它也只能调用c
> X 中的方法。 Z
中是否存在另一个名为 c
的方法并不重要; a
只能调用X
中的c
方法。 Z
中的 c
方法不会覆盖 X
中的 c
方法,因为这是私有(private)的。
在 Z
中调用 c
方法的唯一方法是拥有 Z
引用并直接调用它,因为它不是私有(private)的.
Z z = new Z();
z.c();
将打印
c from class Z
关于Java继承和重写方法——修饰符的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21867688/