Super-class reference variable to a sub-class object accesses the subclass's attribute instead of the super's

Mohamed Fathy :

In my code, I have 3 classes: class A

public class A {
    int x = 1;
    static double y = 3.0;
    public A() {
    x = (int)y;
    }
    public A(int x) {
    this .x = this . getX () + x;
    }
    int getX () {
    return this .x;
    }
    public void f( float z) {
    y *= z;
    }
}

class B, which extends A

public class B extends A {
    int x = 7;
    public B(int x) {
    super (x);
    this .x = x;
    }
    public B() {
    this .y += 1.0;
    }
    int getX () {
    return this .x;
    }
    public void f( long z) {
    y += z;
    }
    public void f( double z) {
    y -= z;
    }
}

and class M, which includes the main function

public class M {
    public static void main ( String [] args ) {
        A a1 = new A();
        System .out. println (a1.x + " " + A.y); // OUT: [ ] [ ]
        B b1 = new B();
        System .out. println (b1.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)b1 ).x); // OUT: [ ]
        A ab = new B (5);
        System .out. println (ab.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)ab ).x); // OUT: [ ]
        A.y = 5.0;
        b1.f (2.0f);
        System .out. println (A.y); // OUT: [ ]
        ab.f (5);
        System .out. println (A.y); // OUT: [ ]
        }
}

Every called function in the main method behaves as expected except for the following two:

        A ab = new B (5);
        System .out. println (ab.x + " " + A.y); // OUT: [ ] [ ]
        System .out. println ((( A)ab ).x); // OUT: [ ]

which gives

5 4.0
5

as output, while I expect it to give

6 4.0
6

Now, as far I understand, upon creating a new object of type B, which is referred to by the reference variable ab of type A, and after invoking the right constructors, the variable x in the super-class should have the value of 6, while the other x in the sub-class equals 5.

If this is right, then, shouldn't ab.x refer to the x in the super-class, which equals 6, since attributes and static methods (in contrary to non-static methods) are dealt with in compile time, which means that the println method should print the variable, within the same class as the reference variable type?

And in case of (( A)ab ).x) shouldn't the x in class B be invisible after casting ab?

I'd be thankful if you can guide me through, why this is happening.

MOnkey :

This statement this.x = this.getX() + x; in A constructorwill call getX from B so the variable x in the super-class will have the value of 5 not 6.

So when you call this statement

A ab = new B (5);

Flow will be

It will call parameterized constructor in class B, then it will encounter super(x) statement, so it will call parameterized constructor in class A where you have this statement this.x = this.getX() + x; which will call getX() of class B which will return this.x ( here x value be returned as 0) so the final value of this.x = this.getX() + x; is (0+5 = 5), and this.x will have a final value of 5. This way in both class A and class B variable x value will be 5.

That is why your following statements are returning

System .out. println (ab.x + " " + A.y); // OUT: [5] [3.0]
System .out. println ((( A)ab ).x); // OUT: [5]

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=168863&siteId=1