问题描述
- stackoverflow上面的java的域不能“重写”问题
-
package test; 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
stackoverflow上面的解释我看了还是不太理解。
1.成员变量是编译时决定我了解,但这与“c1.getObject().x”有什么关系?毕竟c1.getObject()返回的是类B的对象呀?
2.解释里提到了隐藏域,子类的域会隐藏父类同名域,和重写是不一样的。我不太明白这个与答案有什么联系?stackoverflow的问题地址:
http://stackoverflow.com/questions/12589274/slight-confusion-regarding-overriding-where-variables-are-concerned
解决方案
提到了隐藏域,子类的域会隐藏父类同名域,和重写是不一样的。我不太明白这个与答案有什么联系
这就是说两个变量都叫x,但是是两个我完全不同的变量,既然不同的变量,干脆我们就用不同的名字。
看下面的代码,我把派生类的x修改为y,使得派生类的x叫做y
/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
class A
{
int x = 5;
}
class B extends A
{
int y = 6;
}
class SubCovariantTest extends CovariantTest
{
public B getObject()
{
System.out.println("sub getobj");
return new B();
}
}
/* Name of the class has to be "Main" only if the class is public. */
class CovariantTest
{
public A getObject()
{
System.out.println("ct getobj");
return new A();
}
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
CovariantTest c1 = new SubCovariantTest();
System.out.println(c1.getObject().y);
}
}
现在这代码没办法编译了。
System.out.println(c1.getObject().x);
可以编译。
说明派生类定义的那个变量,编译器根本就不承认它的存在。为什么如此?因为
public B getObject()
{
System.out.println("sub getobj");
return new B();
}
你一厢情愿把返回值写成B,但是它仍然只能返回A
这个叫做协变式覆盖
http://blog.csdn.net/kiss_the_sun/article/details/7846413
所以它返回的其实还是被当作A,既然是A,那么显然B定义的类型不作数了。
时间: 2024-09-10 14:24:04