Polymorphism means "many forms."
In Java, it allows one object to take many forms — specifically, the same method name can behave differently depending on context.
🛠 A remote control can operate a TV, a fan, or an AC — same remote (method), but different actions depending on device (object).
| Type | Also Called | Done By | Binding |
|---|---|---|---|
| Compile-time Polymorphism | Static Polymorphism | Method Overloading | Early Binding |
| Run-time Polymorphism | Dynamic Polymorphism | Method Overriding | Late Binding |
| Type | When It Happens | Example | Related To |
|---|---|---|---|
| Early Binding | Compile Time | Method Overloading | Static |
| Late Binding | Runtime | Method Overriding | Dynamic |
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator c = new Calculator();
System.out.println(c.add(2, 3)); // calls int version
System.out.println(c.add(2.5, 3.5)); // calls double version
}
}
✔️ Same method name (add), different parameters = overloading
class Animal {
void sound() {
System.out.println("Animal makes sound");
}
}
class Dog extends Animal {
void sound() {
System.out.println("Dog barks");
}
}
public class Main {
public static void main(String[] args) {
Animal a = new Dog(); // upcasting
a.sound(); // Dog barks (overridden version) → runtime polymorphism
}
}
✔️ sound() method is called based on object type, not reference type.
When a parent class reference is used to refer to a child class object, and overridden method is resolved at runtime, it's called dynamic method dispatch.
class Shape {
void draw() {
System.out.println("Drawing Shape");
}
}
class Circle extends Shape {
void draw() {
System.out.println("Drawing Circle");
}
}
public class Main {
public static void main(String[] args) {
Shape s = new Circle(); // upcasting
s.draw(); // Output: Drawing Circle
}
}
📌 The method call is resolved at runtime, depending on the actual object.
Assigning a child object to a parent reference.
Animal a = new Dog(); // Upcasting
a.sound(); // Allowed (calls overridden method)
✔️ Safe because the object is created as a Dog, but treated generally as an Animal.
Casting a parent reference back to a child object.
Animal a = new Dog(); // Upcasting
Dog d = (Dog) a; // Downcasting
d.sound(); // Works if 'a' is actually a Dog
ClassCastException at runtime.
Animal a = new Cat(); // Object is actually a Cat
Dog d = (Dog) a; // ⚠️ Wrong downcasting
d.sound(); // ❌ Runtime Error: ClassCastException
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog
instanceof:if (a instanceof Dog) {
Dog d = (Dog) a;
d.bark();
} else {
System.out.println("Not a Dog. Cannot downcast safely.");
}
| Concept | Meaning |
|---|---|
| Polymorphism | One interface, many implementations |
| Overloading | Same method name, different params (compile-time) |
| Overriding | Child class redefines parent method (runtime) |
| Early Binding | Method resolved at compile time |
| Late Binding | Method resolved at runtime |
| Upcasting | Parent reference = new Child() |
| Downcasting | (Child) Parent reference |
| Dynamic Dispatch | Overridden method chosen at runtime |
| Question | Answer |
|---|---|
| What is polymorphism? | OOP concept where the same method has different behaviors. |
| Types of polymorphism in Java? | Compile-time (overloading), Runtime (overriding). |
| What is method overloading? | Same method name, different parameters (early binding). |
| What is method overriding? | Child class redefines parent method (late binding). |
| What is dynamic method dispatch? | Calling overridden method using parent reference at runtime. |
| What is upcasting? | Parent reference pointing to child object. |
| What is downcasting? | Converting parent reference back to child. |
| Why is Java polymorphism powerful? | Enables flexible code, loose coupling, code reuse. |