Definition
Polymorphism is one of the essential features of object-oriented programming that allows the class object to behave differently at different times. It is divided into two types.
- Compile time polymorphism
- Runtime polymorphism
Compile Time Polymorphism
Compile time polymorphism is also known as early binding or static polymorphism. In this type of polymorphism, object’s method is invoked at the compile time. It is further divided into operator overloading and function overloading.
Operator Overloading is a type of polymorphism in which an operator is overloaded to give user defined meaning to it. Overloaded operator is used to perform operation on user-defined data type.
// Operator overloading example class Complex { private: int real, imag; public: Complex(int r = 0, int i =0) { real = r; imag = i; } // Called when '+' is used with between two Complex objects Complex operator + (Complex const &obj) { Complex res; res.real = real + obj.real; res.imag = imag + obj.imag; return res; } void print() { cout << real << " + i" << imag << endl; } }; int main() { Complex c1(10, 5), c2(2, 4); // Example call to "operator+" Complex c3 = c1 + c2; c3.print(); }
Function Overloading is a type of polymorphism in which there are many functions with the same name but different number or type of arguments. There are two ways by which we can overload any function.
- By changing the number of argument
- By changing the type of the argument
Two functions having the same name and same parameter list but different return type is not an overloaded function and will result in a compilation error.
#include <iostream> #include <string> using namespace std; class Sum { public: // Overloaded function int add(int num1, int num2) { return num1 + num2; } // Overloaded function int add(int num1, int num2, int num3) { return num1 + num2 + num3; } // Overloaded function string add(string s1, string s2) { return s1 + s2; } }; int main(void) { Sum obj; cout << obj.add(2, 5) << endl; cout << obj.add(8, 10, 1) << endl; cout << obj.add("Hi,", "Hello"); return 0; }
Runtime Polymorphism
Runtime polymorphism is also known as dynamic or late binding or dynamic polymorphism. In the case of runtime polymorphism, the object’s method is invoked at run time.
This type of polymorphism is achieved by Function Overriding. Function overriding occurs when a derived class has a definition for one of the member functions of the base class. That base function is said to be overridden. Function from a base class that is overriden should have the same signature as that of derived class.
#include <iostream> using namespace std; class Base { public: void show1() { cout <<__FUNCTION__ << endl; } virtual void show2() { cout << __FUNCTION__ << endl; } }; class Derived :public Base { public: // Function overridden from base void show1() { cout << __FUNCTION__ << endl; } void show2() { cout << __FUNCTION__ << endl; } }; int main() { Base b; Base* bPtr; //Base class pointer Derived d; // Derived class object bPtr = &d; // Early Binding bPtr->show1(); // Late Binding bPtr->show2(); } // Output Base::show1 Derived::show2
Member function show1()
has been declared in the base class and later redefined in derived class. Irrespective of what type object the base pointer is holding, the program outputs the contents of the function of the class whose base pointer is the type of.
Member function show2()
has been declared as virtual
in the base class and later redefined in derived class. virtual
keyword allow a member of a derived class with the same name as one in the base class to be appropriately called from a pointer. Since base class pointer contains derived class object, the show2
is bound to function show2
of derived class and hence the output.