问题描述
|
为什么下面的代码打印\“ 1 \”?
class A {
int x = 1;
}
class B extends A {
int x = 2;
}
class Base {
A getObject() {
System.out.println(\"Base\");
return new B();
}
}
public class CovariantReturn extends Base {
B getObject() {
System.out.println(\"CovariantReturn\");
return new B();
}
/**
* @param args
*/
public static void main(String[] args) {
Base test = new CovariantReturn();
System.out.println(test.getObject() instanceof B);
System.out.println(test.getObject().x);
}
}
解决方法
因为您指的是不受多态影响的字段。如果改用
getX()
,它将返回2
。
您要问的是在类A
中定义的字段x
的值(因为Base.getObject()
返回A
)。即使CovariantReturn
覆盖了返回B
的方法,您也没有将对象称为CovariantReturn
。
为了进一步说明字段不受多态性的影响-字段访问是在编译时实现的,因此无论编译器看到什么,这就是要访问的内容。在您的情况下,该方法定义为返回A
,因此访问A.x
。另一方面,基于运行时类型调用方法。因此,即使您定义返回A
但返回B
的实例,您调用的方法也会在B
上被调用。
,@ kris979尽管您返回的是B,但我认为区别在于返回类型为A。因此,将打印A中x的值,即1。
,正如Bozho指出的那样-实例变量永远不会受到多态性的影响。让我给你一个简单的小例子。
class Base {
int i = 1;
void method() {
System.out.println(\"in base\");
}
}
class Sub extends Base {
int i = 2;
void method() {
System.out.println(\"in sub\");
}
}
public class Test {
public static void main(String[] args) {
Base obj = new Sub();
obj.method();
System.out.println(obj.i);
}
}
此代码将打印-子和1