What is Polymorphism in OOP?
Learn polymorphism in OOP — compile-time vs runtime, overloading vs overriding, dynamic dispatch — with Java examples and common interview questions answered.
Expected Interview Answer
Polymorphism is the object-oriented principle that lets objects of different classes respond to the same method call in their own class-specific way.
It comes in two forms: compile-time polymorphism (method overloading — same method name, different parameter lists, resolved at compile time) and runtime polymorphism (method overriding — a subclass provides its own implementation of a superclass method, resolved at runtime through dynamic dispatch). Polymorphism lets code be written against a common interface while concrete behavior varies by type, which is the foundation of extensible designs.
- Code written against interfaces, not concrete types
- New types added without changing existing callers
- Enables frameworks, plugins and dependency injection
AI Mentor Explanation
The captain shouts one instruction — "bowl" — and every bowler responds in their own style: the pacer with a bouncer, the leg-spinner with a googly, the off-spinner with flight. Same message, different execution per specialist. That is polymorphism: the caller (captain) doesn’t need to know each bowler’s technique; each object (player) knows how to perform "bowl" its own way, and the right behavior happens automatically.
Step-by-Step Explanation
Step 1
Define a common interface
Declare the shared method in a base class or interface (e.g. speak()).
Step 2
Override in subclasses
Each subclass provides its own implementation of the method.
Step 3
Program to the base type
Callers hold references of the base type and call the shared method.
Step 4
Dynamic dispatch decides
At runtime, the object’s actual class determines which implementation runs.
What Interviewer Expects
- Clear split between compile-time (overloading) and runtime (overriding) polymorphism
- Understanding of dynamic dispatch / virtual methods
- A code example programming against a base type
- Why it matters: extensibility and the open-closed principle
Common Mistakes
- Confusing overloading with overriding
- Saying polymorphism and inheritance are the same thing
- Not knowing that static methods don’t participate in runtime polymorphism
- Giving only a definition with no example
Best Answer (HR Friendly)
“Polymorphism means one interface, many implementations — different object types respond to the same instruction in their own way. It lets developers add new behaviors without rewriting existing code, which keeps large systems flexible and maintainable.”
Code Example
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
double r;
Circle(double r) { this.r = r; }
double area() { return Math.PI * r * r; }
}
class Rectangle extends Shape {
double w, h;
Rectangle(double w, double h) { this.w = w; this.h = h; }
double area() { return w * h; }
}
// Caller programs against Shape; actual type decides behavior
for (Shape s : List.of(new Circle(2), new Rectangle(3, 4))) {
System.out.println(s.area());
}Follow-up Questions
- What is the difference between method overloading and overriding?
- What is dynamic dispatch and how do virtual tables work?
- How does polymorphism relate to the open-closed principle?
- Can constructors be overridden?
MCQ Practice
1. Method overriding is resolved at?
Overriding uses dynamic dispatch — the object’s runtime type picks the implementation.
2. Same method name with different parameter lists in one class is?
That is method overloading — compile-time polymorphism resolved by signature.
3. Which principle does polymorphism most directly enable?
New subclasses extend behavior without modifying existing calling code — open for extension, closed for modification.
Flash Cards
Compile-time polymorphism? — Method overloading — same name, different signatures, resolved by the compiler.
Runtime polymorphism? — Method overriding — subclass implementation chosen by dynamic dispatch.
Dynamic dispatch? — The runtime mechanism (v-tables) that routes a call to the object’s actual class implementation.
Why program to interfaces? — Callers stay unchanged when new implementations are added — extensible design.