Java-ковариантный тип возврата - PullRequest
8 голосов
/ 26 мая 2011

Почему ниже код печатает «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 ]

13 голосов
/ 26 мая 2011

Потому что вы имеете в виду поля, которые не подвержены полиморфизму. Если бы вы вместо этого использовали getX(), он бы возвратил 2.

То, что вы спрашиваете, это значение поля x, определенного в классе A (потому что Base.getObject() возвращает A). Даже если CovariantReturn переопределяет метод для возврата B, вы не ссылаетесь на свой объект как CovariantReturn.

Чтобы немного рассказать о том, как на поля не влияет полиморфизм - доступ к полям реализуется во время компиляции, поэтому, что бы ни видел компилятор, это и есть доступ. В вашем случае метод определяет, чтобы возвратить A, и поэтому A.x доступен. С другой стороны, методы вызываются на основе типа времени выполнения. Таким образом, даже если вы определите, чтобы вернуть A, но вернуть экземпляр B, метод, который вы вызываете, будет вызван на B.

0 голосов
/ 08 января 2013

Как указал Божо - переменная экземпляра никогда не подвержена полиморфизму.Позвольте привести небольшой небольшой пример.

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

0 голосов
/ 26 мая 2011

@ kris979 Хотя вы возвращаете B, я думаю, что разница в том, что тип возвращаемого значения равен A. Следовательно, значение x в A, то есть 1, печатается.

...