Exercise 10.4, the last few calls

Hello, i would like to know why can ee.foo(be) => A.foo(B), i thought if we initialize ee.foo(be), we only have access to the function at class e, as class e is the ceiling of the function you can call. and also for the last question how come ad.foo(cd) get C.foo(B) and not D.foo(C).

See the slides here. All your questions can now be answered by simply saying “that’s what the algorithm presented there resolves to”, but here are some more details:

Specifically, you get A.foo(B) for ee.foo(be) because of all the methods available on an object of static type E (which includes methods inherited from the parent class, which may be overridden), it is the most specific. In other words: The algorithm says A.foo(B), so that is the correct answer.

For the last question, since the static type of ad is A, the most specific compatible method is A.foo(B), and when resolving overriding, D gets the method C.foo(B) which overrode that method of same signature in A. Again, the algorithm says C.foo(B), so that’s the correct answer.

In general, the algorithm presented there is used by the Java compiler and runtime environment for resolving these problems. This algorithm is what you get when you consistently apply the facts that

  • Overloading is resolved at compile time (which considers only the static type)
  • In Java, methods are always defined by both name and argument types. The only exception are function calls, where overloading must be resolved using type information.
  • Overriding is resolved at run time. It respects the above, i.e. you override the method of your parent class that has the same name and type.

If you still have any questions about the algorithm from the slides, feel free to ask.

Hope this helps
Johannes