Polymorphism

    Polymorphism means different forms or the ability to take on different forms.  It is the ability of an entity to become attached to objects of various types. In order for a programming language to have true polymorphism it must have dynamic binding.  Table 1 shows some common object-oriented programming languages which support polymorphism.

    Operations that have multiple meanings, depending on the type of object they are attached to at run time, are known as polymorphic operations.  An example of a polymorphic operator is the C++ keyword write.  Figure 1 shows an example of how objects could be assigned using polymorphism.
 

Eiffel
Java
C++
Ada 95
Yes
Yes
Yes
Yes
Table 1  Language support of polymorphism

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

P : Polygon;
R : Rectangle;
T : Triangle;
S : Square;

-- valid assignments

P := R;
P := T;
R := S;

 

Figure 1 Polymorphism example

    Do not confuse polymorphism with overloading.  Overloading assigns a type to a distinct operation.  Polymorphism is determined at run time while overloading can be determined at compile time.

    When polymorphism is associated with static binding it is normally called ad hoc polymorphism.

    Figure 2 shows and example of polymorphism using C++.
 

#include <iostream.h>
void function (int x);
class shape
 {
 public:
  int pubint;
  shape(): pubint (88) { cout << "\nin shape default constructor";};
  shape (int i): pubint (i) { cout << "\nin shape int constructor";};
  virtual void draw (){ cout << "\nIN CLASS SHAPE\n";
        cout << "\n sh.pubint is: " << pubint;
        return; };
 }; // end of shape class

 class rectangle: public shape
 {
  public:
  rectangle(): shape(77) { cout << "\nin rectangle default constructor";};
  rectangle (int i): shape (i) { cout << "\nin rectangle int constructor";};
  virtual void draw() { cout << "\nIN CLASS RECTANGLE\n";
      cout << "\n rt.pubint is: " << pubint;
      return; };
  }; // end class rectangle

  class square : public rectangle
 {
 public:
   square(): rectangle (66) {cout<<"\nin square default constructor";};
   square(int i): rectangle(i){cout<<"\nin square int constructor";};
   virtual void draw(){cout <<"\nIN CLASS Square\n";
   return; };
 };  // end class square

 int main()
 {
 cout << "You are now in main\n";
 shape sh;    // constructor is called when program enters its scope
 rectangle rt;
 square sq;
 cout << "\nfor sq, shape::pubint is:" << sq.shape::pubint;
 cout << "\nfor sq, rectangle::pubint is:" << sq.rectangle::pubint;
 cout << "\nfor sq, square::pubint is:" << sq.square::pubint;
 cout <<"\nfor sq, pubint is:" << sq.pubint;
 shape* psh;
 psh = &sq; psh -> draw();
 psh = &rt; psh -> draw();
 psh = &sh; psh -> draw();
 int variable = int(&sq);
 cout << "\n\nvariable is: " << variable<< endl;
 int variable2 = (int(psh = &rt)/int(psh = &sq) + 32);
 cout << "variable2 is: "<<variable2<<endl;
 return 0;
}
 

___________________________________________________________

When you run this program you will get the following output
___________________________________________________________

You are now in main

in shape default constructor
in shape int constructor
in rectangle default constructor
in shape int constructor
in rectangle int constructor
in square default constructor
for sq, shape::pubint is:66
for sq, rectangle::pubint is:66
for sq, square::pubint is:66
for sq, pubint is:66
IN CLASS Square

IN CLASS RECTANGLE

 rt.pubint is: 77
IN CLASS SHAPE

 sh.pubint is: 88

variable is: 9644
variable2 is: 33
 

Figure 2      C++ Polymorphism code example

    Figure 3 is a program example taken from the book Ada 95 From the Beginning showing an example of dynamic binding and polymorphism.
 

package Vehicle_Package is
     type Vehicle is tagged private;
     procedure Give_Info(V: Vehicle);

     type Motor_Vehicle is new Vehicle with private;
     procedure Give_Info(M : Motor_Vehicle);

     type Private_Car is new Motor_Vehicle with private;
     procedure Give_Info(P: Private_Car);

     type Van is  new Motor_Vehicle with private;
     procedure Give_Info(VN: Van);

     type Bus is  new Motor_Vehicle with private;
     procedure Give_Info(B: Vehicle);

     type Minibus is new Bus with private;

private
     type Vehicle istaggednull record;

     type Motor_Vehicle isnew Vehicle with
         record
              Reg_Number : string(1..7);
         endrecord;

     type Private_Car isnew Motor_Vehicle with
         record
              Number_Of_Seats : Positive;
         endrecord;

     type Van is new Motor_Vehicle with
         record
              Max_Load : Positive;
         endrecord;

     type Bus is new Motor_Vehicle with
         record
              Number_Of_Passengers : Positive;
              Air_Conditioning : Boolean;
         endrecord;

     type Minibus isnew Bus with
         nullrecord;
end Vehicle_Package;
____________________________________________________

package body Vehicle_Package is
     procedure Give_Info (V : Vehicle) is
     begin
         Put_Line("A vehicle");
     end Give_Info;
 

     procedure Give_Info (M : Motor_Vehicle) is
     begin
         Put_Line("A motor-vehicle");
         Put_Line("Reg no: " & M.Reg_Number);
     end Give_Info;
 

     procedure Give_Info (P : Private_Car) is
     begin
         Give_Info(Motor_Vehicle(P));
         Put_Line("A private car");
         Put(P.Number_Of_Seats, Width => 1);
         Put_Line (" seats");
     end Give_Info;
 

     procedure Give_Info (Motor_Vehicle(VN: Van)) is
     begin
         Give_Info(Motor_Vehicle(VN));
         Put_Line("A van");
         Put(VN.Max_Load, Width => 1);
         Put_Line (" kg max load");
     end Give_Info;
 

     procedure Give_Info (B: Bus) is
     begin
         Give_Info(Motor_Vehicle(B));
         Put_Line("A bus");
         Put(B.Number_Of_Passengers, Width => 1);
         Put_Line (" passengers");
         if B.Air_Conditioning then
             Put_Line ("With air conditioning");
         endif;
     end Give_Info;
end Vehicle_Package;

Figure 3   Ada 95 Polymorphism code example

    According to the Ada 95 Reference Manual, run-time polymorphism is achieved when a dispatching operation is called by a dispatching call.

    The primitive subprograms of a tagged type are called dispatching operations.  A call is termed a dispatching call when the controlling tag can be dynamically determined, in which case the call dispatches to a body that is determined at run time.
 

Go to Dynamic binding or the Table of Contents