Polymorphism in C++

Polymorphism : Means one thing many forms.

In C++, polymorphism is a core principle of object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common superclass. It enables a single interface to represent various types of objects and provides a way to achieve flexibility and extensibility in software design.



1.Compile-time (Static) Polymorphism OR Static Binding OR Early Binding :


Compile-time (Static) Polymorphism means that the code associated with the function is linked at compile time.
Like : Function Overloading, Operator Overloading:

Function OverLoading

When a class have more than one function with same name but different argumen is called Function Overloading.

Ways for Function Overloading

1. By Changing Number of arguments
2. By Changing Type of arguments

2. Run-time (Dynamic) Polymorphism OR Dynamic Binding OR Late Binding :


Run-time (Dynamic) Polymorphism means that the code associated with the function is linked at runtime.
Like : Virtual Function OR Overriding

Function Overriding

When a child class as well as parent class both have same method with same arguments is called Function Overriding.

Function OverLoading using Different number of arguments
#include<iostream>
using namespace std;
     
class Pv2
      {
public :
     
void add(int x, int y)
{
cout<<x+y<<endl;
}
void add(int x, int y, int z)
{
cout<<x+y+z;
}
};
     
int main()
{
Pv2 ob;
ob.add(2,3);
ob.add(2,3,4);
}
Output:
5
9


Function OverLoading Using Different Type of arguments
#include<iostream>
using namespace std;
   
class Pv2
{
   
public :
   
void add(int x, int y)
{
cout<<x+y<<endl;
}
void add(int x, float y)
{
cout<<x+y;
}
};
   
int main()
{
  Pv2 ob;
  ob.add(2,3);
  ob.add(2,3.4f); // must write f for float
}  
   
Output:
5
5.4
Function Overriding
Example:3
#include<iostream>
using namespace std;
    
class Pv4P
{
  protected:
  int x;
  public :
   void display()
   {
    cout<<"Parent Class \n";
   }
};
class Pv4 : public Pv4P
{
public :
void getX()
{
cout<<"Enter the value of x."<<endl;
cin>>x;
}
void display()
{
cout<<"Child Class"<<"and the value of x="<<x<<endl;
}
};
    
int main()
{
  Pv4 obj;
  obj.getX();
  obj.display();
}          
Output:
Enter the value of x.
25
Child Classand the value of x=25
Example:4
Function Overriding In Multi Level Inheritance

#include<iostream>
using namespace std;
class Pv5PP
{
public :
void display()
{
cout<<"Parent Pv5PP Class"<<endl;
}
};
class Pv5P : public Pv5PP
{
public :
void display()
{
cout<<"Parent Pv5P Class \n";
}
};

class Pv5 : public Pv5P
{
public :
void display()
{
cout<<"Child Class"<<endl;
}
};
    
int main()
{
  Pv5 obj;
  obj.display();
  Pv5P obj1;
  obj1.display();
  Pv5PP obj2;
  obj2.display();
}            
Output:
Child Class
Parent Pv5P Class
Parent Pv5PP Class

Function Overriding In Multiple Inheritance


#include<iostream>
using namespace std;
class Pv6A
{
  public :
  void display()
  {
    cout<<"Parent Pv5PP Class"<<endl;
  }
};
class Pv6B
{
  public :
   void display()
   {
    cout<<"Parent Pv5P Class \n";
   }
};
class Pv6 : public Pv6B, public Pv6A
{
  public :
   void display() // will override the parent classes
   {
     cout<<"Child Class"<&l<<endl;
   }
};
    
int main()
{
  Pv6 obj;
  obj.display();
}                
           
Output:
Child Class

Function Overriding In Multiple Inheritance
Example:6
#include<iostream>
using namespace std;
class Pv6A
{
public :
void display()
{
 cout<<"Parent Pv6A Class Display"<<endl;
}
};
class Pv6B
{
public :
void display()
{
 cout<<"Parent Pv6B Class Display \n";
}
};

class Pv6 : public Pv6B, public Pv6A
 <<
public :
void display()
{
display(); // Ambiguity -- which display() function will call
//Pv6A::display();
//Pv6B::display();
}
};
  
int main()
{
Pv6 obj;
obj.display();
}             
Output:
    Ambiguity : will display nothing

Function Overriding Base Class Function Calling

#include<iostream>
using namespace std;
    
class Pv8P
{
  public :
  void display()
   {
    cout<<"Parent Class \n";
   }
};
class Pv8 : public Pv8P
{
  public :
   void display()
   {
     cout<<"Child Class"<<endl;
    }
};
    
int main()
{
  Pv8 obj;
  obj.display(); // invoke display() in derived Class
  obj.Pv8P::display();// invoke display() in Base Class
}
Output:
Child Class
Parent Class

Pointers to Derived Classes

Calling Child class members using base class pointers.
#include<iostream>
using namespace std;
    
class Pv8P
{
public :
void display()
{
    cout<<"Parent Class \n";
}
};

class Pv8 : public Pv8P
{
  public :
  void display()
   {
     cout<<"Child Class"<<endl;
   }
};
    
int main()
{
  Pv8P base; // object of base class created
  Pv8P *ptr;// base class pointer
  ptr= &base;//pointer points to base class object
  ptr ->display();  // will show parent class members only
                        //because parent object in pointer.
    
  Pv8 derived; // derived class object
  ptr = &derived;// base class pointer holding child class object.
 ( ptr)->display();// will call parent class method.
  // Casting from Base class pointer to child class pointer
  ((Pv8 *) ptr)->display();
  /* will show only those members
  which is inherited by parent only not derived class members. */
    
}

Output:
Parent Class
Parent Class
Child Class


Virtual function

A virtual function is a member function of a class, whose functionality can be overridden in its derived classes.It is one that is declared as virtual in the base class using the virtual key word. The function body of base class can be completely replaced with a new set of implementation in the derived class. Virtual , as the name implies,is something that exists in effects but not in reality . The object oriented programming language C++ implements the concept of virtual function as a simple member function , like all member functions of the class. Virtual function is a mechanism to implement the concept of polymorphism i.e. the ability to give different meanings to one function.

Declaration of Virtual Function

class name // base class of C++ virtual function
{
public:
virtual void memberfuctionname ( )// This denotes the C++ virtual function
{
}
};

Properties of virtual function

Dynamic binding: virtual functions are resolved during run time or dynamic binding. The main difference between a non–virtual C++ member function and a virtual member function is in the way they are both resolved. A non- virtual C++ member function is resolved during compile time and hence it is a static binding. Virtual functions are resolved during run time hence it is a dynamic binding.

1. Virtual functions are member functions of a class.
2. Virtual functions are declared with the keyword virtual.
3. Virtual function takes a different functionality in the derived class.

Need for virtual function

Virtual function is needed to implement different functionalities in different derived classes of a base class.

The virtual functions can be inherited. when a virtual function is inherited, its virtual nature is also inherited. This means that when a derived class that has inherited a virtual function is itself used as a base class for another derived class ,the virtual function can still be overridden.
One can inherited a virtual function any number of times.
#include <iostream>
using namespace std;
class vehicle// base class of C++ virtual function
{
public:
 virtual void make ( )//C++ virtual function
 {
    cout <<"member function of base  class vehicle accessed"<<endl;
 }
};

class TwoWheeler : public vehicle
{
 public:
  void make ( )
  {
    cout <<"Two Wheeler accessed"<<endl;
  }
};

class fourwheeler : public vehicle
{
  public:
  void make ( )
   {
    cout <<"Four Wheeler accessed"<<endl;
   }
};

int main ( )
{
vehicle *a, *b, *c;
a = new vehicle ( ); // Dynamic object creation.
a->make ( ) ;
b= new fourwheeler ( ); // up casting // implicit casting :: means automatically casting child to parent
b->make ( );
c= new TwoWheeler( );// up casting
c->make ( );

fourwheeler *x, *y; // down casting // will work fine.
x=(fourwheeler *)new vehicle(); // must have to cast it. explicitly
//x= new vehicle(); // compilation error
x->make();
y= new fourwheeler();
y->make();
} 
Output:
member function of base  class vehicle accessed
Four Wheeler accessed
Two Wheeler accessed
member function of base  class vehicle accessed
Four Wheeler accessed


Pure virtual Function And Abstraction And Interface

A class which contain pure virtual function is called abstract class. Abstract classes cannot be used to instantiate objects and serves only as an interface. Attempting to instantiate an object of an abstract class causes a compilation error.
#include <iostream>

using namespace std;

// Base class
class Shape {
   public:
      // pure virtual function providing interface framework.
      virtual int getArea() = 0;
      
      void setWidth(int w) {
         width = w;
      }

      void setHeight(int h) {
         height = h;
      }

   protected:
      int width;
      int height;
};

// Derived classes
class Rectangle: public Shape {
   public:
      int getArea() {
         return (width * height);
      }
};

class Triangle: public Shape {
   public:
       Triangle()
       {

       }
      Triangle(int w, int h)
      {
        width=w;
        height=h;
      }

      int getArea() {
         return (width * height)/2;
      }
};

int main(void) {
   //Shape obj; // We can not create an object of abstract Class.
   Rectangle Rect;
  // Triangle  Tri; will call default constructor
    Triangle  Tri(2,3);
//
   Rect.setWidth(5);
   Rect.setHeight(7);

   // Print the area of the object.
   cout << "Total Rectangle area: " << Rect.getArea() << endl;

   //Tri.setWidth(5);
   //Tri.setHeight(7);

   // Print the area of the object.
   cout << "Total Triangle area: " << Tri.getArea() << endl;

   cout<<"\nObject Creation at Dynamic time :"<<endl<<endl;
   Shape *Drect, *Dtri;
   Drect= new Rectangle;
   Drect ->setWidth(8);
   Drect ->setHeight(5);
   cout << "Total Rectangle area: " <<Drect ->getArea()<<endl;
   Dtri= new Triangle(4,5);
  // delete Dtri; // Delete will deallocate the memory for Triangle Object.
//   Dtri ->setWidth(2);
//   Dtri ->setHeight(3);
    cout << "Total Triangle area: "<<Dtri ->getArea()<<endl; // after delete line will not execute
   return 0;
}
Output
Total Rectangle area: 0
Total Triangle area: 3
              
Object Creation at Dynamic time :
              
Total Rectangle area: 40
Total Triangle area: 10