0

In the example below, I am confused as to why upcasting seems to refer to some parts of the parent class and some parts of the actual class.

public class B extends A{
   int fi = 15;
   public static void main(String[] args){
       B b = new B();
       b.fi = 20;
       System.out.println(b.fi);
       System.out.println(  (  (A) b  ).fi  );
       System.out.println(  (  (A) b  ).getNum());
   }
   public int getNum(){
       return fi;
   }
}
class A{
   final int fi = 5;
   public int getNum(){
       return fi * 2;
}

The printed results are:

20
5
20

I know this code is written in some inefficient ways, but it's similar to an OCA practice question I've gotten. I would like to know why ((A)b).fi refers to the variable in A, but that ((A)b).getNum() uses the variable and method in B. If upcasting refers to the parent, shouldn't the results be 20 5 10 instead?

2 Answers2

0

There are two forces at play here:

On one hand, the Java compiler uses the type of the reference to resolve names to class members. Because ((A)b) has type A:

  • ((A)b).fi refers to the variable fi in A.
  • ((A)b).getNum() refers to the method getNum in A. You can see this for a fact by for example adding a checked exception to A.getNum() declaration, while leaving the exception out of B.getNum(). The compiler will require you to catch or declare the exception ((A)b).getNum() may throw, while it lets you call b.getNum() without such changes.

On the other hand, Java has dynamic dispatch for methods. Dynamic dispatch means that at run time, the JVM looks what what is the type of the actual object. If the object overrides the method you are calling, the JVM calls the override instead. This means:

  • ((A)b).getNum() will call the method defined in B at run time.
Joni
  • 108,737
  • 14
  • 143
  • 193
  • So you're saying that ((A)b).getNum() on compile time refers to the method getNum() in A, indicating there is a getNum() in A. On runtime it will call the method getNum() in B, as B is the class of the object being referred to? – Reno Gonda Aug 14 '20 at 21:24
0

The method is chosen by the dynamic type (B) but the attribute is chosen by the static type (A).

Maybe one of the links can help you:

elisabeth
  • 21
  • 3