javaoverridingoverloadingdynamic-bindingstatic-binding

Why this static binding doesn't work as i would expect?


I have a question about how this program selects the method.

Code(constructors aside):

class Father {
   int x;
   ..

   public int m(Father f) {
      return (f.x - this.x);
   }
}

class Son extends Father {
   int y;
   ...

   public int m(Father f) {
       return 100;
   }

   public int m(Son s) {
       return super.m(s) + (s.y - this.y);
   }
}

Main:

Father f1, f2; 
Son s1;
f1 = new Father(3);
f2 = new Son(3,10);
s1 = new Son(4,21);
System.out.println(f1.m(s1) + f2.m(s1)); 

I don't understand why f2.m(s1) prints 100. Personally I understood that if there are 2 methods with the same name, if there is an overload the choice is made with static types, and if override it's made with dynamic types;

f1.m(s1) searches dynamically a Father.m(Son) method, but it doesn't exist and Father.m(Father) is chosen instead

f2.m(s1) searches dynamically for a Son.m(Son) method, which exists and is an overload, so i think it should now prioritize static types and that searches for a Father.m(Son) method, which doesn't exist but the closest one is the Father.m(Father). Instead, the Son.m(Father) method is chosen: it is the method that is overloaded by the Son.m(Son) method okay, but it doesn't come out from the static search, so why it is chosen?


Solution

  • f2 is a reference of type Father. Even though the object it references is a Son, the compiler still only allows using any methods that exist in Father when accessing a reference of that type. Therefore there is no other choice but using the method with signature int m(Father) (as it's the only one that exists in Father). Since Son has an override for this method, that override is executed.

    f2.m(s1) searches dynamically for a Son.m(Son) method

    That's where your error is rooted. It's not looking for a Son.m(Son) method, it's looking for a Father.m(Son) method and finds a Father.m(Father) method. Calling the override happens at a later point.