Jim*_*mmy 11 java overriding scjp ocpjp
我正在为SCJP做准备(最近由甲骨文重新命名为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();
}
}
Run Code Online (Sandbox Code Playgroud)
答案是5
,但我选择了6
.
我知道覆盖适用于运行时的方法,而不是变量,但我的思维解释方式println
是:
SubCovariantTest
对象,并且具有有效覆盖getObject()
,因此请使用重写方法是JVM忽略该getObject()
部分的情况,并且总是x
从c1
编译时关联变量?
Sco*_*ott 12
尽管对SubCovariantTest正确完成了覆盖,但由于声明了变量c1,因此答案为5.它被声明为CovariantTest,而不是SubCovariantTest.
运行c1.getObject().x时,它不知道它是SubCovariantTest(没有使用转换).这就是为什么5从CovariantTest返回而不是从SubCovariantTest返回6.
如果你改变了
System.out.println(c1.getObject().x);
Run Code Online (Sandbox Code Playgroud)
至
System.out.println(((SubCovariantTest) c1).getObject().x);
Run Code Online (Sandbox Code Playgroud)
你会得到6你所期望的.
编辑:正如评论中指出的那样
"字段不是在Java中的多态性,只有方法,在子类中的X隐藏了基类中的X,它不会覆盖它." (感谢JB Nizet)
好的,我知道现在回答这个问题有点晚了,但我和我的朋友遇到了同样的问题,这里的答案对我们来说还不是很清楚。所以我只说明我遇到了什么问题以及现在它是如何有意义的:)
现在我明白字段不会被覆盖,而是像miller.bartek指出的那样被隐藏,我也明白覆盖是针对方法的,而不是斯科特指出的字段。
然而,我遇到的问题是这个。在我看来,
c1.getObject().x
Run Code Online (Sandbox Code Playgroud)
这必须转化为:
new B().x // and not newA().x since getObject() gets overrided
Run Code Online (Sandbox Code Playgroud)
计算结果为 6。
而且我不明白为什么 A 类(超类)的变量在没有明确要求这种行为的情况下被 B 类(子类)的对象调用。
从问题的措辞猜测,我觉得 OP 有同样的问题/怀疑。
您可以从 Elbek 的回答中得到提示。将以下几行放在 main 方法中并尝试编译代码:
A a = c1.getObject(); //line 1
B b = c1.getObject(); //line 2
Run Code Online (Sandbox Code Playgroud)
您会注意到第 1 行是完全合法的,而第 2 行给出了编译错误。
因此,当调用函数 getObject() 时,CovariantTest(超级)函数将被 SubCovariantTest(子)函数覆盖,因为这是代码中的有效覆盖,并且 c1.getObject() 将返回新的 B()。
然而,由于超级函数返回类类型 A 的引用,即使在被覆盖之后,它也必须返回类类型 A 的引用,除非我们对它进行类型转换。在这里,B 类是A 类(由于继承)。
所以实际上,我们从 c1.getObject() 得到的不是
new B()
Run Code Online (Sandbox Code Playgroud)
但是这个:
(A) new B()
Run Code Online (Sandbox Code Playgroud)
这就是为什么即使返回了类 B 的对象并且类 B 的 x 值为 6,输出仍为 5。
归档时间: |
|
查看次数: |
1949 次 |
最近记录: |