Java-ковариантный тип возвращаемого значения
Почему ниже код печатает "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);
}
}
3 ответа
Потому что вы имеете в виду поля, которые не подвержены полиморфизму. Если вы вместо этого использовали getX()
, он бы вернулся 2
,
То, что вы спрашиваете, это значение поля x
определено в классе A
(так как Base.getObject()
возвращается A
). Даже если CovariantReturn
переопределяет метод возврата B
, вы не ссылаетесь на свой объект как CovariantReturn
,
Чтобы немного рассказать о том, как на поля не влияет полиморфизм - доступ к полям реализуется во время компиляции, поэтому, что бы ни видел компилятор, это и есть доступ. В вашем случае метод определяет, чтобы вернуть A
так что A.x
Доступ С другой стороны, методы вызываются на основе типа времени выполнения. Так что, даже если вы решили вернуть A
но вернуть экземпляр B
, метод, который вы вызываете, будет вызван на B
,
@kris979 Несмотря на то, что вы возвращаете B, я думаю, что разница в том, что тип возвращаемого значения равен A. Следовательно, значение x в A, то есть 1, печатается.
Как отметил Божо, переменная экземпляра никогда не подвержена полиморфизму. Позвольте привести небольшой пример.
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