What is Polymorphism?

On: April 3, 2026
What is Polymorphism

Learn polymorphism in object-oriented programming (OOP) with clear examples and easy explanations. Understand method overloading, method overriding, runtime and compile-time polymorphism, and how they improve code flexibility, reusability, and scalability.

Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows a single function, method, or interface to perform different behaviors depending on the object or input.

In simple terms, polymorphism means “one name, many forms,” where the same operation behaves differently in different situations.

Polymorphism = “Many Forms”

In programming, it means:

One name (function/method) can do different things depending on the object or input.

Simple Real-Life Example

Think of the word “run”:

  • You run in a race
  • A machine runs
  • A program runs

Same word → different meanings → polymorphism

Programming Example

  • For a circle → it draws a circle
  • For a square → it draws a square

Same function name → different behavior

Code Example

class Shape {
public:
    void draw() {
        cout << "Drawing shape";
    }
};

class Circle : public Shape {
public:
    void draw() {
        cout << "Drawing circle";
    }
};

class Square : public Shape {
public:
    void draw() {
        cout << "Drawing square";
    }
};

What happens?

Shape* s;

Circle c;
Square sq;

s = &c;
s->draw();   // Drawing circle

s = &sq;
s->draw();   // Drawing square

Same draw() → different outputs
This is polymorphism

Why Do We Need Polymorphism?

  • Code Reusability
    Write one function and use it for multiple types of objects, reducing duplicate code.
  • Flexibility in Code
    The same interface can handle different data types or objects, making code adaptable.
  • Cleaner & Maintainable Code
    Reduces complexity and keeps code organized, especially in large projects.
  • Extensibility (Easy to Add Features)
    You can add new classes or behaviors without changing existing code.
  • Supports Dynamic Behavior
    Objects can behave differently at runtime, making programs more realistic.
  • Improves Readability
    Using a common method name makes code easier to understand.
  • Reduces Conditional Statements
    Avoids multiple if-else or switch cases by using a common interface.
  • Better Abstraction
    Focus on what to do, not how it is done, improving design quality.
  • Real-World Modeling
    Helps represent real-world scenarios where the same action behaves differently.

Types of Polymorphism

There are two main types:

Types of Polymorphism

1.Compile-Time Polymorphism (Static Polymorphism)

Decided at compile time (before program runs)

How it works?

The compiler decides which function to call based on:

  • Number of parameters
  • Type of parameters

A ) Method Overloading

Same function name, but:

  • Different number of arguments OR
  • Different data types

Example (C++)

class Math {
public:
    int add(int a, int b) {
        return a + b;
    }

    int add(int a, int b, int c) {
        return a + b + c;
    }

    float add(float a, float b) {
        return a + b;
    }
};

What’s happening?

Math m;

m.add(2, 3);        // calls int version
m.add(2, 3, 4);     // calls 3-arg version
m.add(2.5, 3.5);    // calls float version

Compiler chooses function before execution

B) Operator Overloading

Operators behave differently based on operands.

int a = 5 + 3;        // addition
string s = "Hi " + "Bro"; // concatenation

Same + → different behavior

Key Features

  • Fast (no runtime decision)
  • No inheritance required
  • Less flexible than runtime polymorphism

2.Run-Time Polymorphism (Dynamic Polymorphism)

Decided at runtime (during execution)

How it works?

  • Uses inheritance
  • Uses function overriding
  • Uses pointers/references
  • Uses virtual functions (C++)

Method Overriding

Child class provides its own version of parent function.

Example (C++)

class Animal {
public:
    virtual void sound() {
        cout << "Animal sound";
    }
};

class Dog : public Animal {
public:
    void sound() {
        cout << "Dog barks";
    }
};

class Cat : public Animal {
public:
    void sound() {
        cout << "Cat meows";
    }
};

Runtime Behavior

Animal* a;

Dog d;
Cat c;

a = &d;
a->sound();   // Dog barks

a = &c;
a->sound();   // Cat meows

Decision happens at runtime, not compile time

What is virtual in C++?

The virtual keyword is used in a base class to ensure that a function can be overridden in a derived (child) class and that the correct function is called at runtime, not compile time.

Definition

virtual enables runtime polymorphism by allowing function calls to be resolved dynamically (during execution).

Why Do We Need virtual?

Without virtual, C++ uses early binding (compile-time)
With virtual, C++ uses late binding (runtime)

This ensures the program calls the correct function based on the actual object, not the pointer type.

Without virtual (Problem ❌)

class Animal {
public:
    void sound() {
        cout << "Animal sound";
    }
};

class Dog : public Animal {
public:
    void sound() {
        cout << "Dog barks";
    }
};
Animal* a;
Dog d;

a = &d;
a->sound();   // ❌ Output: Animal sound

Even though object is Dog, it calls Animal function
Because binding happens at compile time

With virtual (Solution ✔️)

class Animal {
public:
    virtual void sound() {
        cout << "Animal sound";
    }
};

class Dog : public Animal {
public:
    void sound() {
        cout << "Dog barks";
    }
};
Animal* a;
Dog d;

a = &d;
a->sound();   // ✔️ Output: Dog barks

Now correct function is called at runtime

How virtual Works Internally

When you use virtual:

Compiler creates:

  • vtable (Virtual Table) → stores function pointers
  • vptr (Virtual Pointer) → inside each object

At runtime:

  • Object’s vptr points to correct function in vtable
  • Function call is resolved dynamically

Key Concepts Related to virtual

1.Function Overriding

Child class replaces parent function

2.Base Class Pointer

Animal* a;

Needed for runtime polymorphism

3.Dynamic Binding

Function call decided at runtime

Virtual Destructor

class Base {
public:
    virtual ~Base() {
        cout << "Base destructor";
    }
};

Ensures:

  • Proper cleanup of derived class objects
  • Prevents memory leaks

Pure Virtual Function (Advanced)

class Shape {
public:
    virtual void draw() = 0;  // pure virtual
};

Makes class abstract
Child class must implement this function

When to Use virtual?

  • When using inheritance
  • When behavior should change in child classes
  • When using base class pointers/references
  • When implementing polymorphism

Why virtual is important?

Without virtual:
Base class function will always be called ❌

With virtual:
Correct child function is called ✔️

Behind the scenes

  • Uses vtable (virtual table)
  • Each object keeps pointer to correct function
  • Enables dynamic dispatch

Key Features

  • Flexible
  • Supports real-world modeling
  • Slightly slower (runtime decision)
  • Requires inheritance

Difference Between Both

FeatureCompile-TimeRun-Time
Decision TimeBefore executionDuring execution
SpeedFasterSlightly slower
ConceptOverloadingOverriding
InheritanceNot requiredRequired
FlexibilityLessMore

Simple Analogy

  • Compile-time → Teacher assigns roles before play
  • Run-time → Actor changes role on stage dynamically

Compile-Time Polymorphism

Other Names:

  • Static Polymorphism
  • Early Binding
  • Static Binding

All mean the same thing:

Decision is made before program runs

Run-Time Polymorphism

Other Names:

  • Dynamic Polymorphism
  • Late Binding
  • Dynamic Binding

All mean:

Decision is made during program execution

Example WITHOUT virtual ❌ (Compile-Time Binding)

Code

#include <iostream>
using namespace std;

class Animal {
public:
    void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        cout << "Dog barks" << endl;
    }
};

int main() {
    Animal* a;
    Dog d;

    a = &d;
    a->speak();   // What will this print?

    return 0;
}

Output

Animal speaks

Why this happens (Important)

  • Pointer type = Animal*
  • Object type = Dog

But C++ ignores object type here
It only looks at pointer type at compile time

So:

  • Compiler decides → call Animal::speak()
  • This is called Static Binding / Early Binding

Key Point

Without virtual, function call depends on pointer type, not actual object.

Example WITH virtual ✔️ (Run-Time Binding)

Code

#include <iostream>
using namespace std;

class Animal {
public:
    virtual void speak() {
        cout << "Animal speaks" << endl;
    }
};

class Dog : public Animal {
public:
    void speak() {
        cout << "Dog barks" << endl;
    }
};

int main() {
    Animal* a;
    Dog d;

    a = &d;
    a->speak();   // Now what?

    return 0;
}

Output

Dog barks

Why this happens

Because of virtual:

Compiler delays decision until runtime
It checks actual object type (Dog)
Calls Dog::speak()

This is called:

What Changes Internally?

Without virtual:

  • Direct function call
  • No extra mechanism
  • Faster
  • No polymorphism

With virtual:

C++ creates:

vtable (Virtual Table)

  • A table storing addresses of virtual functions

vptr (Virtual Pointer)

  • Hidden pointer inside each object

Flow at Runtime:

  1. a = &d;
  2. Object d has its own vptr
  3. vptr points to Dog’s vtable
  4. a->speak():
    • Looks into vtable
    • Finds Dog::speak()
    • Calls it ✔️

Side-by-Side Comparison

FeatureWithout virtualWith virtual
BindingCompile-timeRun-time
Function CalledBased on pointerBased on object
Polymorphism❌ No✔️ Yes
SpeedFasterSlightly slower
FlexibilityLowHigh

Real-Life Analogy

Without virtual:
You call a person by their job title only
(“Hey Employee”) → always same response

With virtual:
You call based on actual person
(“Hey Developer / Manager”) → different response

Basic Interview Questions

  • What is polymorphism?
  • What are the types of polymorphism?
  • Difference between compile-time and runtime polymorphism?
  • What is method overloading vs method overriding?
  • What is the virtual keyword in C++?
  • Why do we use virtual functions?

Core Concept Questions

  • What happens if we don’t use virtual in function overriding?
  • Why do we need a base class pointer for runtime polymorphism?
  • Explain early binding vs late binding.
  • How does C++ decide which function to call?
  • Can we achieve polymorphism without inheritance? (Yes → overloading)

Code-Based Questions

Interviewer may give code like this:

class A {
public:
    void show() { cout << "A"; }
};

class B : public A {
public:
    void show() { cout << "B"; }
};

int main() {
    A* obj = new B();
    obj->show();
}

Question:

What will be the output and why?

Expected Answer:

  • Output = A (because no virtual)
  • Uses compile-time binding

Same with virtual

virtual void show()

Output = B
Because of runtime polymorphism

Advanced Questions

  • What is a virtual table (vtable)?
  • What is a virtual pointer (vptr)?
  • How does dynamic dispatch work internally?
  • What is the cost of using virtual functions?
  • Can constructors be virtual? (No ❌)
  • Can destructors be virtual? (Yes ✔️, very important)

Tricky Questions

  • What happens if base class destructor is not virtual?
    👉 Can cause memory issues / incomplete cleanup
  • Can we override a non-virtual function?
    👉 Yes, but no runtime polymorphism
  • Difference between virtual and pure virtual?
    👉 Pure virtual makes class abstract
  • What is an abstract class?
    👉 Class with at least one pure virtual function

Scenario-Based Questions

  • When should you use polymorphism in real projects?
  • Give a real-world example of polymorphism.
  • Where have you used virtual functions?
  • How would you design a system using polymorphism?

Top 5 Must-Prepare Questions

If you prepare only these, you’re safe 👇

  1. What is polymorphism with example?
  2. Compile-time vs runtime polymorphism
  3. What is virtual and why needed?
  4. Output-based question (with/without virtual)
  5. What is vtable and how it works?

For detailed understanding of Platform Devices and Drivers on Linux, refer to the Linux documentation on Platform Devices and Drivers .

Leave a Comment