When typecasting an child class's object to parent class, what happens with the variables of the object?

133 Views Asked by At
class HelloWorld 
{
    public static void main(String[] args) 
    {
         A a =  new B();
         System.out.println(a.getX()); 
         a.show();
    }
}

class A {
    int x = 10;
    
    public A() {
    }
    
    public int getX() {
        return x;
    }
    
    public void show(){
        System.out.println("A show");
    }   
}

class B extends A{
    int x = 20 ;
    
    public B() {
        super();
    }
    
    @Override
     public void show(){
        System.out.println("B show");
    }
}

Why is the output this?

10
B Show

I understand 'B Show'. Since the object is of class B, it will call the method that is overridden in B. But do not understand why it is printing '10' in output even though the object of B has value of x equal to 20. Please help me understand this.

1

There are 1 best solutions below

0
rzwitserloot On
  • All Bs are As with extra bells and whistles. That's what extends A {} means.
  • Fields inherit for free. In fact, because fields do not have an implementation (merely defining them is where it ends), if you declare a field with the same name in a subtype, you now have 2 fields. Thus, your B instances have 2 fields. They are both named x but are completely separate fields. In real code you should never do this; it's very confusing.
  • Removing int x; from your B class means B still has a field of type int named x - it inherits that one from A. It just means it now doesn't also have a second field also named x also of type int.

The 'name' of a method in java is not just the method name, it also includes the parameter types. You can't override' unless they match. In other words:

class A { 
  void foo(int x) {}
}

class B extends A {
  void foo(long y) {}
}

Here B's foo method is not the same name as A's and therefore foo does not override. If you slap an @Override on it, you'll get a compiler error. It is not possible to cause B's foo code to run with A a = new B(); a.foo(5); because given that the reference here (a - a pointer, variables point at objects) is of type A, the compiler doesn't know about B's foo(long) method and thus couldn't possibly call it here. Make that B method void foo(int x) and that is an override and A a = new B(); a.foo(5); would call B's, not A's, because java does dynamic dispatch.

The same principle applies to fields. With A a = new B(); a.x refers to the x field defined in class A.