Object-Oriented Technology
Concepts

Polymorphism

Polymorphism (literally, "many forms") is defined as two or more methods
  1. with the same name
  2. that perform semantically similar operations
  3. but are implemented differently.

There are three different forms of polymorphism - operator polymorphism, method polymorphism, and class polymorphism.

Operator Polymorphism

Consider an operator such as the addition sign '+':

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

  1. has the same name in both cases ('+'),
  2. performs semantically similar operations in both cases (addition),
  3. but is implemented differently in both cases (since integral and decimal arithmetic are algorithmically different, both when performed by hand and by a computer).

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.

Method Polymorphism

Consider a computer language that defines two methods called 'plus':

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

  1. have the same name in both cases ('plus'),
  2. perform semantically similar operations in both cases (addition),
  3. but are implemented differently in both cases (since integral and decimal arithmetic are algorithmically different, both when performed by hand and by a computer).

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:
  1. is defined identically ('aheadFull()') in the context of a subclass-superclass relationship,
  2. performs semantically similar operations (change speed to max),
  3. but is implemented differently (different max speeds).

Class Polymorphism

Class polymorphism is the ability for one class to masquerade as another. This usually occurs between parent classes and their children. Because a child class can do everything its parent class can do, the child can masquerade as its parent.

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:

  1. they are defined identically with the same name in the context of a subclass-superclass relationship,
  2. they perform semantically similar (actually, identical) operations

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.


[home]
[OO] [Java] [memorial ships]
[humor] [income tax repeal]


Copyright (C) 1998 LDJ Trust