In addition to facilitating the re-use of code, inheritance provides a common base data type that lets us refer to objects of specific types through more generic types of references; in particular, we can mix objects of different subtypes in the same collection. For example
SeaCreature s = new Fish(...);
...
s.swim();
The data type of an instance of the Fish
class is a Fish
, but it is also a kind of SeaCreature
. Java provides the ability to refer to a specific type through more generic type of references.
There may be situations that require a reference to an object using its more generic subtype rather than its most specific type. One such situation is when different subtypes of objects in the same collection (array, list, etc.) are mixed. For example:
SeaCreature creatures = new SeaCreature[2];
creatures[0] = new Fish(...);
creatures[1] = new Mermaid(...);
...
creature[currentCreature].swim();
This is possible because both Fish
and Mermaid
are SeaCreatures
.
Note that the Fish
and Mermaid
classes provide two different implementations of the swim
method. The correct method that belongs to the class of the actual object is located by the Java virtual machine. That means that one method call
String s = x.getname();
can call different methods depending on the current reference of x
.
The principle that the actual type of the object determines the method to be called is called polymorphism (Greek for "many shapes"). The same computation works for objects of many forms and adapts itself to the nature of the objects. In Java, all instance methods are polymorphic.
There is an important difference between polymorphism and overloading. With an overloaded method, the compiler picks the correct method when translating the program, before the program ever runs. This method selection is called early binding. With a polymorphic method, selection can only take place when the program runs. This method of selection is called late binding.