Polymorphism


The word 'polymorphism' has been derived from two greek words- 'poly' which means many, and 'morphs' means forms. Hence, it has many forms i.e. an entity behaves differently on different circumstances.


Real World Scenario


A boy posses  different behaviour in different situations. In school, he is a student, when he is in market he behave like costumer, at home he is a son, in the play ground, he is a sportsman. Here, a single person have characteristics according to the situation.


Types of polymorphism





1. Compile time polymorphism: 

In this, object's method is invoked at the compile time. It is also known as static binding (or, early binding).     

 It can   be achieved in two ways-


    a) Function overloading:

 A function is said to be overloaded when there exists two or more functions with same name but with different  number of arguments and their different types. The function is called by matching the types and the number of arguments.  Consider the below          example.


Example: 

//C++ program to demonstrate function overloading

#include<iostream.h>

#include<conio.h>

using namespace std;

class solid

{

  public:

    vol(int a)     //function with int type parameter

    {

      return (a*a*a);

    }

    //overloaded function with int, float and double type parameters

    float vol(int l, float b, double h)     

    {

      return l*b*h;

     }

};

int main()

{

  solid obj;

  cout<<"Volume of the cube: "<<obj.vol(4)<<endl;     //called the 1st function

  cout<<"Volume of the cuboid: "<<obj.vol(5, 4.2, 0.5);    //calling the overloaded function

  return 0;

}


OUTPUT:




b) Operator overloading:

C++ provides a feature where operators can be overloaded i.e. the normal C++ operators, such as +, -, / etc., are given  additional meanings by applying user defined data types.

     

For example, a plus(+) operator can be used to concatenate two strings and to add two integers.


Rules for overloading operator 

i. Only built-in operators in C++ can be overloaded.

ii. To overload unary operator, arguments must not be passed. In case, an argument must be taken if overloaded through a friend function. 

iii. To overload binary operator, at least one argument is required. If overloaded through a friend function,it takes two arguments.


Syntax:

return_type class_name operator sign_mark()

{

...

}


Example 1:

//C++ program to demonstrate unary operator overloading

#include<iostream.h>

#include<conio.h>

using namespace std;

class number

{

  int a;

  public:

    void get()

    {

       cout<<"Enter any number: ";

       cin>>a;

    }

    void operator ++()    //overloading operator function

    {

      a=a+1;

    }

    void display()

    {

      cout<<"Value after increament: "<<a;

    }

};

int main()

{

  number n;

  n.get();

  ++n;       

  n.display();

  return 0;

}

OUTPUT: 





Example 2:

//C++ program to demonstrate binary operator overloading

#include<iostream.h>  

#include<conio.h>

using namespace std;  

class line  

{  

  public:  

     int m, cm; 

     length(int a, int b)

     {

     m=a;

     cm=b;

     } 

     line operator +(line d)     //overloading operator function

     {  

        line obj;  

        obj.m = m + d.m;

        obj.cm = cm + d.cm;

        return obj;  

     }  

     display() 

     {  

        cout<<"Total length: "<<m<<"m"<<cm<<"cm";  

     }   

};  

int main()  

{  

   line x, y, sum;  

   x.length(2, 5);

   y.length(9, 4); 

   sum=x+y;

   sum.display();

    return 0;  

OUTPUT: 



Please note: Operators .*, ., ::, sizeof, ?: cannot be overloaded.


2. Runtime polymorphism:

In this, object's method is invoked at the run time. It is also known as dynamic binding (or, late binding). It can be  achieved by function overriding.

      Function overriding When a function, which is already defined in the base class, is redefined in the derived class with same return type and parameter, it is known as function overriding. As such, the function of the derived class is executed i.e. the function in the sub class overrides that in the base class. It is achieved by using virtual function.


Virtual Function

A virtual function is a member function in the base class which is then redefined in several derived classes as per requirement. It exist in effect but not in reality.

Rules of virtual function:

ii. They can neither be static nor a friend function.

iii. It is declared using keyword virtual.

iv. They must be defined in a base class.

v. It must be specified as public access specifier. 

vi. The prototype of virtual function must be same in base and derived classes. 

vii. They are accessed through object pointers to achieve run-time polymorphism.

viii. Constructors can never be virtual yet destructors can be virtual.


Syntax:

class base_class

{

  public:

     virtual return_type fun()

     { }

};

class sub_class : access_mode base_class

{

  public:

    return_type fun()

    { }

};


Example :

 //C++ program to demonstrate virtual function

#include<iostream>

#include<conio.h>

using namespace std;

class base

{

  public:

    virtual void display()        //virtual function

    {

      cout<<"Function of base pointer type is called.."<<endl;

    }

};

class derived : public base

{

  public:

    void display()           //overriding function

    {

      cout<<"Base class function is overriden. ";

    }

};

int main()

{

  base *b;         //base class pointer

  derived d;        //sub class object

  b= &d;

  b -> display();      //late binding

  return 0;

}


OUTPUT:






In the above program, the object's method is invoked at the run time i.e. the function is linked with the data member and the method is invoked at the run time. Hence, it is called late binding.


The below chart shows the difference between compile time polymorphism and run time polymorphism: