This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
"Bcos" is not the real word. Please go through this thread for avoiding such stuff.
Regarding your query please have a look at the following two points.
For Overloaded methods,
During compilation the compiler sees ONLY the "Reference Type" to invoke the methods.
At runtime to invoke the method (when its actually the time to actually transfer the control to the called method), the "actual instance" is being used!
In your case1,
ah1 -> reference type -> belonging to Animal class
the object being referred by "ah1" -> of type Horse
In both the cases, the variable (instance) you have used to invoke was that of type "Animal".
In case1, the Animal class does have the method "eat()" and hence there were no errors during compilation. But at the runtime the actual method being invoked was that of type "Horse" since the actual object being referred by the instance variable "ah1" is of type "Horse".
Based on the same logic explained above, since the Animal class does NOT have a matching method "eat(String arg)" [the one which takes a String parameter], the compiler is unable to find the match! That's why you get a compiler error.
If you instance variable is of type "Horse" itself, there are no issues.