关于覆盖变量的地方有轻微的混淆 [英] Slight confusion regarding overriding where variables are concerned

查看:112
本文介绍了关于覆盖变量的地方有轻微的混淆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正准备参加SCJP(最近由甲骨文重新命名为OCPJP),我在模拟考试中遇到的一个特殊问题让我很困惑,答案描述并不能解释清楚的事情。



这是一个问题:

  A 
$ $
int x = 5;
}
B类延伸A
{
int x = 6;
}
公共类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扩展CovariantTest
{
public B getObject()
{
return new B() ;
}
}

答案是 5 ,但我选择 6



我知道覆盖适用于运行时的方法,而不是变量,但我的思维解释 println 的方式是:


  1. 来电getObject on c1

  2. c1实际上是一个 SubCovariantTest 对象,对于有一个有效的覆盖
    > getObject()
    ,所以使用重写方法

  3. 覆盖返回B,所以从B抓取x,这是6

是JVM忽略 getObject()部分的情况,并始终采用 x c1 作为变量在编译时关联?

解决方案

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



当运行c1.getObject()。x时,它不知道它是SubCovariantTest(没有使用转换)。这就是为什么5从CovariantTest返回而不是6从SubCovariantTest返回。



如果你改变了

 的System.out.println(c1.getObject()X。); 

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

您将获得预期的6美元。



<编辑:正如评论中指出的那样



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


I'm preparing for the SCJP (recently rebranded as OCPJP by Oracle) and one particular question that I got wrong on a mock exam has confused me, the answer description doesn't explain things clear enough.

This is the question :

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();
    }
}

The answer is 5, but I chose 6.

I understand that overriding applies to methods at runtime, and not variables, but the way my mind interpreted that println was :

  1. call getObject on c1
  2. c1 is actually a SubCovariantTest object, and has a valid override for getObject(), so use the overridden method
  3. The override returns B, so grab x from B which is 6

Is it a case of the JVM ignoring the getObject() part, and always taking x from c1 as variables are associated at compile time?

解决方案

Although the override is done properly for SubCovariantTest the answer is 5 because of how the variable c1 is declared. It is declared as a CovariantTest and not as a SubCovariantTest.

When c1.getObject().x is run, it does not know that it is a SubCovariantTest (no casting was used). This is why 5 is returned from CovariantTest and not 6 from SubCovariantTest.

If you change

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

to

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

you will get 6 as you expected.

Edit: As pointed out in the comments

"fields are not polymorphic in Java. Only methods are. The x in the subclass hides the x in the base class. It doesn't override it." (Thanks to JB Nizet)

这篇关于关于覆盖变量的地方有轻微的混淆的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆