# Polymorphism

Polymorphism is one of the fundamental principles in object-oriented programming (OOP) and is derived from two Greek words: "poly" (meaning "many") and "morph" (meaning "form"). It refers to the ability of objects of different classes to be treated as objects of a common base class. Polymorphism allows you to write more generic and reusable code by emphasizing the common behavior of objects rather than their specific types.

There are two primary forms of polymorphism: compile-time (static) polymorphism and run-time (dynamic) polymorphism.

1.  **Compile-time (Static) Polymorphism**:

    * Compile-time polymorphism occurs when the decision about which method or function to call is made at compile time, based on the method's or function's signature and the arguments provided.
    * It is also known as method overloading and operator overloading.
    * **Method Overloading:** In C++, you can define multiple methods in the same class with the same name but different parameter lists. The appropriate method to call is determined at compile time based on the number and types of arguments.



    ```cpp
    class MathOperations {
    public:
        int Add(int a, int b) {
            return a + b;
        }
        
        double Add(double a, double b) {
            return a + b;
        }
    };
    ```

    * **Operator Overloading:** In C++, you can redefine operators (e.g., `+`, `-`, `*`) for user-defined types. The operator to use is determined at compile time based on the operator symbol used in the code.



    ```cpp
    class Complex {
    public:
        Complex operator+(const Complex& other) {
            Complex result;
            result.real = this->real + other.real;
            result.imaginary = this->imaginary + other.imaginary;
            return result;
        }
    };
    ```
2.  **Run-time (Dynamic) Polymorphism**:

    * Run-time polymorphism allows you to invoke different methods or functions based on the actual type of an object at runtime.
    * It is achieved through inheritance and virtual functions (in C++), enabling the use of pointers or references to the base class to call overridden methods of derived classes.



    ```cpp
    class Animal {
    public:
        virtual void MakeSound() {
            std::cout << "Some generic animal sound." << std::endl;
        }
    };

    class Dog : public Animal {
    public:
        void MakeSound() override {
            std::cout << "Woof! Woof!" << std::endl;
        }
    };

    class Cat : public Animal {
    public:
        void MakeSound() override {
            std::cout << "Meow!" << std::endl;
        }
    };
    ```



    In the example above, the `MakeSound` method is declared as `virtual` in the base class `Animal`. This allows objects of derived classes, like `Dog` and `Cat`, to provide their own implementations of the method. When calling `MakeSound` through a base class pointer or reference, the appropriate derived class version is executed at runtime:



    ```cpp
    Animal* myAnimal;
    myAnimal = new Dog();
    myAnimal->MakeSound(); // Calls Dog's MakeSound method.
    delete myAnimal;

    myAnimal = new Cat();
    myAnimal->MakeSound(); // Calls Cat's MakeSound method.
    delete myAnimal;
    ```

{% hint style="info" %}
**Note :** A method in derived class overrides the method in base class if the method in derived class has the **same name**, **same return type** and **same parameters** as that of the base class.
{% endhint %}

Polymorphism promotes code flexibility, extensibility, and reusability by allowing you to write code that works with objects of different derived classes through a common base class interface. It is a powerful concept in OOP and is extensively used in designing complex software systems.

