kris979
kris979

Reputation: 81

java covariant return type

Why does below code prints "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);
}
}

Upvotes: 8

Views: 1557

Answers (3)

Rishikesh Dhokare
Rishikesh Dhokare

Reputation: 3589

As Bozho pointed out - instance variable are never affected by polymorphism. Let me give you a quick small example.

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);
    }
}

This code will print - in sub and 1

Upvotes: 0

Ashish K Agarwal
Ashish K Agarwal

Reputation: 1172

@kris979 Though you are returning B, i think what makes the difference is that the return type is of A. Hence value of x in A i.e. 1 is printed.

Upvotes: 0

Bozho
Bozho

Reputation: 597234

Because you are referring to fields, which are not affected by polymorphism. If you instead used getX(), it would've returned 2.

What you are asking is, the value of field x defined in class A (because Base.getObject() returns A). Even though CovariantReturn overrides the method to return B, you are not referring to your object as CovariantReturn.

To expand a bit on how fields are not affected by polymorphism - field access is realized at compile time, so whatever the compiler sees, that's what's accessed. In your case the method defines to return A and so A.x is accessed. On the other hands methods are invoked based on the runtime type. So even if you define to return A but return an instance of B, the method you invoke will be invoked on B.

Upvotes: 13

Related Questions