I studied polymorphism and understand that it can do dynamic method binding like below.
Assuming that class Animal is abstract class.
public class An
The type you use in a local variable declaration (as in your ArrayList example) is not usually that significant. All you have to ensure is that the type of myList (the word to the left of the name 'myList') has to be more specific than the type of any method parameter that takes myList.
Consider:
ArrayList words = new ArrayList();
sort(words);
removeNames(words);
public void sort(Collection c) ... blah blah blah
public void removeNames(List words) ...
I could have replaced the type of 'words' to just be List. It doesn't make any difference to the readability or the behaviour of my program. I could not define 'words' to be Object though. That's too general.
On a related note, when you define a public method, you should give careful consideration about the types of the method's parameters, since this has a direct effect on what the caller can pass in. If I defined sort differently:
ArrayList words = new ArrayList();
// this line will cause a compilation error.
sort(words);
public void sort(LinkedList c) ... blah blah blah
The definition of sort is now very restrictive. In the first example, the sort method allows any object as the parameter, so long as it implements Collection. In the second example, sort only allows a LinkedList, it won't accept anything else (ArrayLists, HashSets, TreeSets and many others). The scenarios in which the sort method can be used are now quite limited. This might be for good reason; the implementation of sort may rely on a feature of the LinkedList data structure. It is only bad to define sort this way if people using this code want a sort algorithm that works for things other than LinkedLists.
One of the main skills in writing java libraries is deciding the types of method parameters. How general do you want to be?