racerX
racerX

Reputation: 1092

Accessing subclass members through super class reference variables

I am reading a Java text book and came across a doubt. A reference variable of a superclass can be assigned a reference to an object of any subclass derived from that superclass. However, when a reference to a subclass object is assigned to a superclass reference variable, you will have access only to those parts of the object defined by the superclass. Example:

class X {
    int a;
    X(int i) {
        a = i; 
    }
}

class Y extends X {
    int b;
    Y(int i, int j) {
        super(j);
        b = i;
    }
}

class SupSubRef {
    public static void main(String args[]) {
        X x = new X(10);
        X x2;
        Y y = new Y(5, 6);
        x2 = x; // OK, both of same type
        System.out.println("x2.a: " + x2.a);
        x2 = y; // still Ok because Y is derived from X
        System.out.println("x2.a: " + x2.a);
        // X references know only about X members
        x2.a = 19; // OK
        // x2.b = 27; // Error, X doesn't have a b member
    }
}

So, in the above example, x2 (a variable of the superclass type) can refer to an object of the derived class, bit it cannot access subclass specific members. However, in the discussion on method overriding, it is shown that a superclass reference variable's call to an overridden method can be resolved to the subclass method. But the subclass method is not defined in the superclass, so isn't this a contradiction, how is the superclass reference variable able to access the subclass specific method? Example:

class Sup {
    void who() {
        System.out.println("who() in Sup");
    }
}
class Sub1 extends Sup {
    void who() {
        System.out.println("who() in Sub1");
    }
}
class Sub2 extends Sup {
     void who() {
         System.out.println("who() in Sub2");
     }
}

class DynDispDemo {
    public static void main(String args[]) {
        Sup superOb = new Sup();
        Sub1 subOb1 = new Sub1();
        Sub2 subOb2 = new Sub2();
        Sup supRef;
        supRef = superOb;
        supRef.who();
        supRef = subOb1;
        supRef.who();
        supRef = subOb2;
        supRef.who();
    }
}

The output from the program is shown here:

who() in Sup
who() in Sub1
who() in Sub2

So how is supRef able to access the who method in the subclass object?

Upvotes: 2

Views: 3400

Answers (1)

Sweeper
Sweeper

Reputation: 271050

When the textbook says that you can't access subclass-specific members with x2, it meant that you can't access them at compile time.

To the compiler. x2 is of type X (though it's really of type Y at runtime), so when the compiler sees you trying to access stuff defined in Y, it spots and says "that is not defined in X. You can't do that!"

However, we all know that at runtime, x2 stores a reference to a Y object. At runtime, you can indeed access members defined in Y with x2. You can prove this by using reflection.

At runtime, x2 is of type Y, so obviously Y's implementation will be called.

Upvotes: 3

Related Questions