The ability to change form is known as polymorphism. Java supports different kinds of polymorphism like oveloading and overriding.
The same method name (method overloading) or operator symbol (operator overloading) can be used in different contexts.
In method overloading, multiple methods having same name can appear in a class, but with different signature. And based on the number and type of arguments we provide while calling the method, the correct method will be called.
Java doesn't allow operator overloading except that "+" is overloaded for class String. The "+" operator can be used for addition as well as string concatenation.
Overloading may be also called compile time polymorphism. Matching ot methods are done at compile time and any errors are thrown at compile time.
We can override an instance method of parent class in the child class. When you refer to a child class object using a Parent reference (e.g. Parent p = new Child()) and invoke a method, the overriden child class method will be invoked. Here, the actual method called will depend on the object at runtime, not the reference type. Overriding is not applicable for static methods or variables (static and non-static). In case of variables (static and non-static) and static methods, when you invoke a method using a reference type variable, the method or variable that belong to the reference type is invoked.
Example: Consider a class Shape with a draw() method. It can have subclasses Circle and Square. An object of Circle or Square can be assigned to a Shape reference type variable at runtime (e.g. Shape s = new Circle();). While executing draw() on the Shape reference, it will draw a Circle or Square based on the actual object assigned to it at runtime.
You need to follow some rules while overriding. You can find the rules of overriding @ http://javajee.com/rules-for-overriding.
In java 5 and above, we can confirm whether we are doing a valid override by using the @Override annotation above the subclass's method. Compiler will throw error when @Override is applied on static methods, static variables or instance variables.
Overriding may be also called runtime polymorphism.
While some people consider this also as a form of polymorphism, many people see this only as a feature provided by Java.
Within a class declaration, a field name can associate with different types and a method name can associate with different parameter and return types. Java supports parametric polymorphism via generics.
An example is a list which can accept the type of data it contains through generics.
List<String> list = new ArrayList<String>();