- 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 types of references.
-
There may be situations that require a reference to an object using its more generic supertype 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:
ArrayList <SeaCreature> creature = new ArrayList <SeaCreature>;
Creature.add( new Fish(...));
Creature.add( new Mermaid(...));
...
creature.get(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
. When a subclass redefines the implementation of a method from its superclass, it is called overriding the method. Note that for overridden methods in Java, the actual method to call is always determined at run time. This is called dynamic binding or late binding.
-
The principle that the actual type of the object determines the method to be called is polymorphism (Greek for “many shapes”). The same computation works for objects of many forms and adapts itself to the nature of the objects.
-
Overloading a method is often confused with overriding a method because the names are so similar. Overloading a method means to keep the name of the method, but change the parameter list. In this case, the compiler can choose the method that is actually called because the signatures are different. The Math class has many examples of overloaded methods. For example Math.max(double a, double b) and Math.max(int a, int b) are overloaded versions of the max method. The compiler determines which one to call depending on the type of the arguments that are being passed in.