java - 关于覆盖变量的地方有点困惑

标签 java overriding scjp ocpjp

我正在准备 SCJP(最近被 Oracle 更名为 OCPJP),我在模拟考试中做错的一个特定问题让我感到困惑,答案描述并没有足够清楚地解释事情。

这是问题:

class A 
{
    int x = 5;
} 
class B extends A 
{
    int x = 6;
} 
public class CovariantTest 
{
    public A getObject() 
    {
       return new A();
    } 
    public static void main(String[]args) 
    {
       CovariantTest c1 = new SubCovariantTest();
       System.out.println(c1.getObject().x);
    }
}

class SubCovariantTest extends CovariantTest 
{
    public B getObject() 
    {
       return new B();
    }
}

答案是5,但我选择了6

我知道重写适用于运行时的方法,而不适用于变量,但我的想法解释 println 的方式是:

  1. 在 c1 上调用 getObject
  2. c1 实际上是一个 SubCovariantTest 对象,并且有一个有效的覆盖 对于getObject(),所以使用覆盖的方法
  3. 重写返回 B,所以从 B 中获取 x,即 6

这是 JVM 忽略 getObject() 部分的情况,并且总是从 c1 中获取 x 因为变量在编译时关联时间?

最佳答案

虽然对 SubCovariantTest 的覆盖是正确的,但由于变量 c1 的声明方式,答案是 5。它被声明为 CovariantTest 而不是 SubCovariantTest。

运行 c1.getObject().x 时,它不知道它是一个 SubCovariantTest(未使用转换)。这就是为什么从 CovariantTest 返回 5 而不是从 SubCovariantTest 返回 6 的原因。

如果你改变

System.out.println(c1.getObject().x);

System.out.println(((SubCovariantTest) c1).getObject().x);

如你所料,你会得到 6。

编辑:正如评论中所指出的

“字段在 Java 中不是多态的。只有方法是。子类中的 x 隐藏了基类中的 x。它不会覆盖它。” (感谢 JB Nizet)

关于java - 关于覆盖变量的地方有点困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12589274/

相关文章:

java - 如何使用二分查找找到用户编号

Java - 在这种情况下,委托(delegate)是一个好的解决方案吗?

java - 自动装箱/拆箱 java Long 类型作为返回值时出现意外的 NullPointerException

java - JVM 规范和 Java 编译器代码对 SCJP 准备有用吗?

java - 如何从匿名内部类调用特定的父构造函数?

java - 如何防止多次同时加载非缓存值?

使用服务帐户和密码连接到 MS SQL Server 的 Java 代码

java - 使用for循环为多个 ImageView 设置图像资源

Java - 父类正在调用子类的方法?

c++ - 错误 C3646 : 'closure' : unknown override specifier