Doubt in inheritance

5

I have a question about inheritance. I have the following code:

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 A {
    int x =5;
}

class B extends A {
    int x = 10;
}

class SubCovariantTest extends CovariantTest{

    @Override
    public B getObject(){
        return new B();
    }

}

Why when I call c1.getObject() returns A instead of returning B ? If I am instantiating c1 as SubCovariantTest , should not call method getObject() that returns new B() ?

When I create an instance of the parent class as a child class

CovariantTest c1 = new SubCovariant()

Should not look at the methods / attributes of the instantiated class new Subcovariant() ?

    
asked by anonymous 28.05.2015 / 16:31

2 answers

4

In fact your code returns B . However its B object has two attributes of the same name x .

See below, I pasted your code here and debugging I could inspect the returned object:

Unlike methods, you do not override attributes.

In order not to create a new attribute of the same name, and thus avoid conflicts, B should change the value of the declared attribute to A . This can be done by using a boot block:

class B extends A {
    { x = 10; }
}

Or a constructor:

class B extends A {
    public B() { x = 10; }
}

But still the question remains: why did Java access the X of A and not B ? Simple: In method main you have used type CovariantTest , whose method returns A .

So Java made the binding static for the x attribute of A , since the compiler determined that the return would be A , even if in execution the object is of type B .

Accessing attributes is not polymorphic as methods.

So by keeping the two attributes of the same name x , but changing the type of the c1 variable, you could access the x of B . So:

SubCovariantTest c1 = new SubCovariantTest();

And the result would be 10 , however it is not good practice to do this.

    
28.05.2015 / 17:04
4

You're correct to say that your code should call the method that returns new B() , but in fact, that's what it does. See below:

public class CovariantTest {

    public static void main(String[] args){
        CovariantTest c1 = new SubCovariantTest();
        System.out.println(c1.getObject().x);
    }

    public A getObject(){
        System.out.println("pai");
        return new A();
    }
}

class SubCovariantTest extends CovariantTest{

    @Override
    public B getObject(){
        System.out.println("sub");
        return new B();
    }
}

class A {
    int x = 5;
}

class B extends A {
    int x = 10;
}

Output:

  

sub
  5

The confusion is occurring when calling the variable x , which is not being accessed through a getter() method, consequently it takes the variable x of the CovariantTest class, because it is not possible to overload variables, occurs with methods.

If you change the excerpt System.out.println(c1.getObject().x); to System.out.println(c1.getObject().y); and change class B to:

class B extends A {
    int y = 10;
}

In the hope that this code will compile and return the y of class B, you can forget, because the compiler does not know any variable y in class A, so it will return an error.

    
28.05.2015 / 17:08