What I think is most important while understanding the concept of Dynamic and Static Binding is that many times we think both types of bindings cannot take place within the scope of a program - that both these two are mutually exclusive This is not true. Its just that the two happen at different stages of the program execution and throw an error that time if any ambiguity is found. For example, in your case:
public class BindingQuestion {
public static void main (String[] args){
Super one = new Super();
Super two = new Sub();
Sub three = new Sub();
two.methodC(three)
}
}
During compile time ----------------
When the program is being compiled, the java compiler will traverse through each and every executable code. When it comes to
two.methodC(three)
it will first check if methodC(three) with this signature is available in the class of the type SUPER. Why Super? Because objects in java are accessed through reference. When you do this:
Super two = new Sub();
This means, for the reference two of type Super, you are pointing to an object of SUB. Which is fine. Why? Because in java, a subclasses always have a few extra properties besides the ones implanted into it by its superclass. So from the piece of code above all the properties of SUB which are common with two will work just fine - they will be easily accessed by the reference variable of SUPER type.
So, the compiler checks if the method
After the compiler has executed through the program and not found any ambiguity in terms of the type of the reference matching with the methodC(three) is present in the SUPER class or not.
According to the structure of inheritance that you have provided, is there a method called methodC is the SUPER class. Answer is yes! It does exists. Now, do the arguments match? In other words does the signature match? The answer is yes. Because in SUPER the signature expected in public void methodC(Sub arg). And guess what? Three, is of type SUB. So compiler will pass this line without creating any errors.
Coming to Run time
You must remember that Objects and invoked only and only at runtime. Check of types of methods and signatures is done during compile time.
Now, Java Runtime instance, while invoking the object two, realizes that actually the object two is of SUB class and invokes the method in the SUB class.
Hope this helped.