Originally posted by Harwinder Bhatia:
When "Dynamic Method Invocation" is applied in the first case, why isn't it applied in the second? What is the rationale behind it?
It isn't applied in the second case because there is no reason to apply it. Dynamic method invocation is only used when a method is overridden. In the second example, there is no overridden method. Therefore, dynamic method invocation is not used.
Let's take a look at that example and see what we really have going on.
In this case, we have creates two new objects. Both of these objects have a run-time type of B, but b1 has a compile-time type of A while b2 has a compile-time type of B. Now, if we remember what we have done with our methods, we'll see something that is teh key to this whole thing.
Notice that, in class A, we have this method signature:
While, in class B, we have this method signature:
So, what does that mean? Well, class B extends class A. Therefore, class B inherits the method m1(A) from class A. However, class B overloads that method (it DOES NOT override it). The result is that class A has one method named m1 while class B has two methods named m1.
When you compile this, the compiler is going to try to determine which method should be invoked. It starts by looking at the type of the variable on which the method is being invoked. The compile-time type of b1 is A, so the compiler looks into the definition of the class A to find a suitable method. It finds one (and only one as the overloaded method is in B, not A). It then checks to see if that method is overridden. It is not, so this is the appropriate method to invoke.
I hope that makes this a bit clearer for you. If you really want to get to the gritty details of this, check out the JLS:
§15.12 Method Invocation Expressions.