C++ - Polymorphism

Polymorphism is one of the key principles of object-oriented programming (OOP) that allows objects of different classes to be treated as objects of a common base class. It enables a single interface to be used to represent multiple types of objects. Polymorphism is achieved through method overriding and virtual functions.

Suppose we have a base class called Shape that defines a common behavior for different shapes, and two derived classes Circle and Rectangle that inherit from Shape and provide their own implementation of the common behavior.

#include <iostream>
class Shape {
public:
    virtual void draw() {
        std::cout << "Drawing a shape" << std::endl;
    }
};
class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle" << std::endl;
    }
};
class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a rectangle" << std::endl;
    }
};

In this example, the Shape class has a virtual function draw(). The Circle and Rectangle classes inherit from Shape and override the draw() function with their specific implementations.

Now, let's create objects of different shapes and use them polymorphically:

int main() {
    Shape* shape1 = new Circle();
    Shape* shape2 = new Rectangle();
    shape1->draw();   // Polymorphic call to draw() in Circle class
    shape2->draw();   // Polymorphic call to draw() in Rectangle class
    delete shape1;
    delete shape2;
    return 0;
}

In the main() function, we create pointers of type Shape* and assign them objects of Circle and Rectangle classes. Since both Circle and Rectangle are derived from Shape, we can treat them as Shape objects.

When we call the draw() function using the shape1 and shape2 pointers, polymorphism comes into play. The actual function called depends on the type of the object being referred to at runtime. It dynamically resolves the correct function to call based on the type of the object. This is known as dynamic or late binding.

In this example, the draw() function is called polymorphically, resulting in the specific implementation of the draw() function in the respective derived classes (Circle and Rectangle) being invoked. This allows us to achieve different behaviors for different shapes while using a common interface.