There are three different forms of polymorphism - operator polymorphism, method polymorphism, and class polymorphism.
a = b+c, where a, b, and c are integral values, and
w = x+y, where w, x, and y are decimal values.
The '+' operator meets the definition of polymorphism because it
Operator polymorphism is, strictly speaking, not an OO concept because it predates OO languages and is, in fact, an artifact of common arithmetic. As such, operator polymorphism is a concept that dates back thousands of years.
a = plus(b,c), where a, b, and c are integral values, and
w = plus(x,y), where w, x, and y are decimal values.
The 'plus' methods meet the definition of being polymorphic because they
Method polymorphism is achieved in OO languages by creating a child class that reimplements (or "overrides") one or more methods of its parent class. These methods -- because they have the same name in the child and parent classes, perform semantically similar operations, but have different body implementations -- are polymorphic methods.
For another example, consider the Ship class:
public class Ship { // class declaration
// Field Variables:
private float speed; // speed of ship, in knots
// Field Access Methods:
public void aheadFull() { // method to set speed to max value
speed = 12.0; // assume a max speed of 12 kts for any ship
} // end of aheadFull() method
public void setSpeed ( // method to set speed to arbitrary value
float new_speed) { // value of new speed to be set
speed = new_speed; // set speed to supplied value
} // end of setSpeed() method
} // end of class
The Ship class is then used as a basis for the creation of classes
that model special kinds of ships, such as CargoShip and SailingShip:
public class CargoShip // cargo ship class declaration
extends Ship { // defined as a specialization of Ship
// Field Access Methods:
public void aheadFull() { // method to set speed to max value
setSpeed (14.5); // say cargo ships can go 14.5 kts max
// note: setSpeed() inherited from Ship class
} // end of aheadFull() method
} // end of class CargoShip
public class SailingShip // sailing ship class declaration
extends Ship { // defined as a specialization of Ship
// Field Access Methods:
public void aheadFull() { // method to set speed to max value
setSpeed (9.0); // say sailing ships can go 9 kts max
// note: setSpeed() inherited from Ship class
} // end of aheadFull() method
} // end of class SailingShip
In the above examples the method aheadFull() is polymorphic as it appears
in three forms - one for Ship, one for CargoShip, and one for SailingShip.
In all cases, the method:
For example, given the Ship example above, we can say:
CargoShip MaryDeare = new CargoShip();
Ship mystery_ship;
mystery_ship = MaryDeare;
Here, we first create an instance of a CargoShip, called MaryDeare,
then define a variable of type Ship, called mystery_ship. We then
set the Ship variable to reference the CargoShip instance. The
cargo ship object instance can then be referenced using its real
data type by using the variable MaryDeare, and it can also be referenced
using its masquerade - the Ship variable mystery_ship. However, when
the object is referenced using mystery_ship, only methods that are
defined in the Ship class can be used (since mystery_ship is of type
Ship). When it is referenced using MaryDeare, all of its CargoShip
methods can be used (since MaryDeare is of type CargoShip).This works because all the methods of Ship are inherited by CargoShip. Such inherited methods meet two of the three criteria for polymorphism:
Because they are implemented identically they are, strictly speaking, not polymorphic unless they are overridden in the child class. However, strict method polymorphism, while acceptable, is not essential to class polymorphism. It is sufficient that classes be related by inheritance for a child to masquerade as its parent.
Class polymorphism is achieved by declaring variables to be of a parent class type, while having those variables actually reference objects of one of the parents' child classes. In this manner, for example, a ship simulation program could be written, using Ship variable declarations, that will work for any kind of ship -- CargoShip, SailingShip, etc. -- by supplying objects of the subclass at run-time. This allows code to be written that has both the consistency checking advantages of strong typing and the flexibility advantages of weak typing.