0
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.

VGR
  • 40,506
  • 4
  • 48
  • 63
  • 2
    `int x = 10;` and `int x = 20;` are *two different fields.* The second one does not in any way override the first one. Methods can be overridden; fields cannot. That said, if the constructor of B contained `x = 20;` (without the `int`β€”it is vital that the code does not declare a new field!), you would see what you expected to see. – VGR Apr 17 '23 at 12:04
  • 1
    duplicate of https://stackoverflow.com/questions/10722110/overriding-member-variables-in-java-variable-hiding ? – nomoa Apr 17 '23 at 12:05
  • To answer the literal question in the title: **nothing** happens to the fields. In fact **nothing** happens to the object at all! Casting a reference in Java doesn't affect the object it references at all. It only changes the compile-time type, which can affect which methods you can call. At runtime that cast is nothing more than a check that it's allowed: that's all the JVM really does. – Joachim Sauer Apr 17 '23 at 12:30

1 Answers1

0
  • 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.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72