The entire dynamic method dispatch is based on the rule that an object reference of the super class can refer to an object of any subclass in the hierarchy. This can be explained with the following example.
Since superclass and subclass share IS A relationship, every Faculty is a Person. So, whenever Java expects Person, a Faculty can be used. This kind of implicit casting is called upcasting.
Unlike in upcasting, every Person need not be a Faculty. Thus, if we use Person in place of Faculty, explicit casting needs to be done. Therefore, we need to use explicit typecasting in order to perform this operation. This kind of explicit casting is called as downcasting.
In runtime polymorphism, the call to an overridden method is resolved at runtime instead of compile time. It occurs when an overridden method is called using an object reference of superclass. Remember that you can only call methods which are present in the super class.
Now let us extend the previous mentioned example with another subclass to "Person" class: NonTeaching class. Now the class diagram is as follows:
The below class demonstrates the runtime polymorphism for the above class diagram.
As can be seen from the code above, Java calls appropriate method depending on the object pointed to by the object reference. In the first case, the object reference p is pointed to the object of Faculty class. So, the printDetails() from the Faculty class is called. In the second case, p points to object of NonTeaching class. Thus, the printDetails() from the NonTeaching class is called.
Always remember that the dynamic method dispatch is applied only to method that is defined in the super class, overridden in subclass and invoked using an object reference of superclass.

