Let\'s take this simple Java code:
public class Animal {
public void eat() {
System.out.println(\"Generic Animal Eating Generically\");
}
}
public
I expected the compiler to invoke the eat() method from the Animal class reference, not the Horse object reference.
Let's correct this statement first. The variable ah is a reference of type Animal and the statement new Horse() creates an instance of type Horse and assigns it to an Animal reference.
Now that the terminologies are clear, this behavior is expected and is termed as runtype-polymorphism or dynamic method dispatch. At compile time, eat() is resolved based on the reference type which is of type Animal, but at runtime, the method that will be called is based on the instance type which is Horse.
how can I know for sure which method the compiler is going to invoke when I have a generic reference variable types referring to an object type
You could follow these simple steps :
ah.eat() is calling the method eat. Animal ah = new Horse(), the reference type is Animal that is the parent classAnimal ah = new Horse(), the instance type is Horse which is the child class.If all the above conditions are satisfied, you are looking at runtype polymorphism and the method from the child class will be called. In any other scenario, the method to be called will be resolved based on the reference type.
It would also pay to understand that a child class inherits methods from its parents. Lets say that you delete the public void eat() method from Horse class, you are no longer Overrding the eat() method; however, the public void eat(String s) method in Horse is still said to Overload the inherited eat method from Animal. Next, lets add a public void eat(String s) method in Animal. With this addition, you are now Overloading the eat method in Animal and Overrding it in Horse class. No matter how you change the code, the 4 steps mentioned above will always help you decide which method will be called.