Solution

ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2017/imperative-programming/7/c/solution

The printed lines are:
f with X at M
f with Y at N
f with Y at N
Method overloading first uses static types. The receiver m has static type M, whose available signatures are f(X) and f(Y). Argument x selects f(X); y selects f(Y); and z, statically Z, also selects f(Y) because that is the most specific available applicable signature. N.f(Z) is not available through the static receiver type.
Only after a signature is selected does dynamic dispatch choose an override for the runtime receiver N. That class overrides f(Y) but not f(X), explaining all three lines. The shared argument object's runtime class does not trigger a second overload-resolution pass.

New to topics? Read the docs here!