Doubt in inheritance

Asked

Viewed 103 times

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 the method getObject() returning new B()?

When I create an instance of the Father class as a Son class

CovariantTest c1 = new SubCovariant()

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

2 answers

4

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

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

Dois atributos

Unlike the methods, you nay overwrite attributes.

Not to create a new attribute of the same name, and thus avoid conflicts, B shall change the value of the attribute declared in A. This can be done using a boot block:

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

Or a builder:

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

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

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

Attribute access nay is polymorphic as to methods.

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

SubCovariantTest c1 = new SubCovariantTest();

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

  • 2

    +1, perfect, I only published mine because I was already halfway through and I think I explained it in a slightly different way :)

  • Perfect and clear explanation. It is even difficult to accept only one.

4

You are correct in saying 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;
}

Exit:

sub
5

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

If you change the section System.out.println(c1.getObject().x); for 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 you the y class B, you can forget it, because the compiler knows no variable y class A, so you will be given an error.

  • 1

    Ball show. Perfect answers that cleared the explanation. I did not pay attention to the fact of overwriting variables!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.