2

I get why a.get() returns 20, it is because of dynamic binding since object of B is created at runtime so it calls the get() in class B

But why does a.x print 10?

class A {
  int x = 10;

  int get() {
     return x;
  }
}

class B extends A {
  int x = 20;

  int get() {
    return x;
  }
}

class Main {
  public static void main(String[] args) {
    A a = new B();
    System.out.println(a.get()); //20
    System.out.println(a.x); //10
  }
}

If you could also explain the memory used in storing the object here.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    Also here: [How does Java handle fields when upcasting?](https://stackoverflow.com/questions/14108343/how-does-java-handle-fields-when-upcasting) – Rafael Dias da Silva Jul 12 '19 at 20:53
  • This is one good reason to keep fields `private` unless the class is a simple (`final`) DTO -- in OOP, the state of an object should be accessed indirectly through methods. – Mick Mnemonic Jul 12 '19 at 20:56

3 Answers3

8

Simply because in Java, only methods are polymorphic and not fields. When you reference a field, the compiler will use the declared type. When you reference a method, dynamic dispatch at runtime will select the correct polymorphic operation.

Phillip
  • 6,033
  • 3
  • 24
  • 34
  • @Philip Also, the space taken by object `a` will be the size of B right ? – Gagan Ganapathy Sudhir Ajjikut Jul 12 '19 at 20:57
  • @GaganGanapathySudhirAjjikut What do you mean by "object `a`"? `a` is not an object, it is a *variable* which holds *reference* to object. Reference is simple number used by JVM to locate object in memory. This can be helpful: [What is the difference between a variable, object, and reference?](https://stackoverflow.com/q/32010172) – Pshemo Jul 12 '19 at 20:59
2

The best way to think of it is that your object a is of type A. But because of the way you declared it, it can "steal" functions from the B class and will do so if they overlap.

Since a is of type A, calling a.x will return the public variable "x" stored in the A class. Since it never has to refer to methods in B in this process, it will refer to the x in the A class, not the B class.

But when you call a.get(), it calls the a.get() of the B class, which grabs the x = 20 defined in the B class.

Let me know if that helps!

codeman51
  • 156
  • 8
0

With respect to objects in Java there is a distinction between declared type vs actual type. In this case object a is of declared type and b actual type. One way to think about it is that methods of the declared type will be executed when called on Override methods in a subclass. x is a field in class a therefor not subject to polymorphic behaviors in this aspect. more on actual vs declared type here: http://ice-web.cc.gatech.edu/ce21/1/static/JavaReview-RU/OOBasics/ooPoly.html

With respect to memory in the stack the bucket for variable a points to an object of class B with field x with a value of 20. Not sure if this answers your memory question.

griffin_cosgrove
  • 419
  • 8
  • 16