Java Notes
Complete guide to polymorphism in Java — compile-time vs runtime polymorphism, method dispatch, upcasting, downcasting, and designing extensible systems with polymorphic code.
Polymorphism means "many forms." In Java, it's the ability of a single interface to represent different underlying types. The same method call can behave differently depending on the actual object type.
Polymorphism is arguably the most powerful OOP concept. It lets you write flexible, extensible code that works with objects you haven't even created yet.
Two Types of Polymorphism
| Type | Mechanism | Binding | Also Called |
|---|---|---|---|
| Compile-time | Method Overloading | Static (compile time) | Static Polymorphism |
| Runtime | Method Overriding | Dynamic (runtime) | Dynamic Polymorphism |
Compile-Time Polymorphism (Overloading)
The compiler decides which method to call based on the argument types:
public class Calculator {
public int calculate(int a, int b) {
return a + b;
}
public double calculate(double a, double b) {
return a + b;
}
public int calculate(int a, int b, int c) {
return a + b + c;
}
public String calculate(String a, String b) {
return a + b; // String concatenation
}
}
public class Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.calculate(5, 3)); // int version
System.out.println(calc.calculate(2.5, 3.7)); // double version
System.out.println(calc.calculate(1, 2, 3)); // three-param version
System.out.println(calc.calculate("Hello", " World")); // String version
}
}8 6.2 6 Hello World
Runtime Polymorphism (Overriding)
The JVM decides which method to call based on the actual object type at runtime. This is the real power:
📧 Email to alice@email.com | Subject: Order #1234 | Body: Your order shipped! 📱 SMS to +1-555-0123: Code: 7891 🔔 Push [ChatApp] to bob_device: New message! 📧 Email to team@company.com | Subject: Calendar Reminder | Body: Meeting at 3pm 📱 SMS to +1-555-0456: Delivery arriving Total cost: $0.102
Key insight: NotificationService.sendAll() doesn't know about Email, SMS, or Push specifically. It works with the base Notification type. You can add SlackNotification tomorrow without changing sendAll()!
Upcasting and Downcasting
Upcasting (Child → Parent Reference)
Always safe, implicit:
Dog dog = new Dog("Rex", 3, "Labrador");
Animal animal = dog; // Upcasting - implicit, always safe
animal.eat(); // ✅ Works - defined in Animal
animal.sleep(); // ✅ Works - defined in Animal
// animal.bark(); // ❌ Compile error - Animal doesn't know about bark()The object is STILL a Dog in memory. But through the Animal reference, you can only access Animal's interface.
Downcasting (Parent Reference → Child)
Explicit, can fail at runtime:
public class Main {
public static void main(String[] args) {
Animal animal = new Dog("Rex", 3, "Labrador"); // Upcast
// Check before downcasting!
if (animal instanceof Dog) {
Dog dog = (Dog) animal; // Downcast - explicit
dog.bark(); // ✅ Now we can access Dog methods
}
// Without check — DANGEROUS
Animal cat = new Cat("Whiskers", 2);
// Dog wrong = (Dog) cat; // ❌ ClassCastException at runtime!
// Java 16+ pattern matching
if (animal instanceof Dog d) { // Check + cast in one step
d.bark();
}
}
}Polymorphism with Interfaces
Interfaces provide the purest form of polymorphism:
Students by GPA: Bob (GPA: 3.2) Alice (GPA: 3.8) Charlie (GPA: 3.9) Products by price: Mouse ($29.99) Keyboard ($79.99) Laptop ($999.99)
Polymorphism in Collections
import java.util.*;
public class Main {
public static void main(String[] args) {
// List of different shapes - all treated as Shape
List<Shape> canvas = new ArrayList<>();
canvas.add(new Circle(5, "Red"));
canvas.add(new Rectangle(4, 6, "Blue"));
canvas.add(new Triangle(3, 4, 5, "Green"));
canvas.add(new Circle(2, "Yellow"));
// Polymorphic operations
double totalArea = 0;
for (Shape shape : canvas) {
System.out.printf("%s - Area: %.2f%n", shape.getClass().getSimpleName(), shape.area());
totalArea += shape.area();
}
System.out.printf("Total canvas area: %.2f%n", totalArea);
}
}The Power: Open/Closed Principle
Polymorphism enables the Open/Closed Principle — code is open for extension but closed for modification:
Common Mistakes
- Assuming the reference type determines behavior:
``java Animal a = new Dog(); a.makeSound(); // Calls Dog's version, NOT Animal's! ``
- Forgetting that fields are NOT polymorphic:
```java class Parent { String name = "Parent"; } class Child extends Parent { String name = "Child"; }
Parent p = new Child(); System.out.println(p.name); // "Parent" — fields use reference type! ```
- Unsafe downcasting:
``java Animal a = new Cat(); Dog d = (Dog) a; // ❌ ClassCastException! Cat is not a Dog ``
- Overloading when you mean overriding:
``java class Child extends Parent { // This is OVERLOADING (different params), not overriding! public void process(String s, int x) { } // Parent has: public void process(String s) { } } ``
Best Practices
- Program to interfaces/abstractions, not concrete types
- Use polymorphism to eliminate
if-elsechains andswitchon type - Prefer runtime polymorphism for extensibility
- Always use
@Overrideto catch overloading-by-mistake - Check with
instanceofbefore downcasting - Design class hierarchies for polymorphic use from the start
Interview Questions
Q1: What is polymorphism? The ability of a single interface to represent different underlying types. Same method name, different behavior depending on the actual object.
Q2: Difference between compile-time and runtime polymorphism? Compile-time: method overloading, resolved by compiler based on argument types. Runtime: method overriding, resolved by JVM based on actual object type.
Q3: Can polymorphism work with fields? No. Only methods are polymorphic. Field access uses the reference type, not the object type.
Q4: What is the advantage of polymorphism? Extensibility — you can add new types without modifying existing code. The processing code works with the base type and automatically handles all subtypes.
Q5: What is dynamic method dispatch? The JVM mechanism that determines at runtime which overridden method to call based on the actual object pointed to by the reference.
Q6: Can you achieve polymorphism without inheritance? Yes, through interfaces. A class can implement an interface and be used polymorphically through that interface reference.
Q7: What is parametric polymorphism in Java? Generics. List<T> works with any type T — that's parametric polymorphism. The same code structure operates on different types.
Q8: What is upcasting and downcasting in Java? Upcasting: assigning child object to parent reference (Animal a = new Dog()). Always safe, happens implicitly. Downcasting: casting parent reference back to child (Dog d = (Dog) a). Risky, requires explicit cast, can throw ClassCastException if the actual object isn't compatible.
Q9: How does polymorphism work with method overloading? Method overloading is compile-time polymorphism — the compiler decides which overloaded version to call based on argument types at compile time. This is also called static binding or early binding. No runtime decision is involved.
Q10: What is the instanceof operator and when is it used with polymorphism? instanceof checks the actual runtime type of an object: if (animal instanceof Dog). It's used before downcasting to avoid ClassCastException. With Java 16+ pattern matching: if (animal instanceof Dog d) combines check and cast.
Q11: Can constructors be polymorphic? No. Constructors are not inherited and cannot be overridden, so they cannot be polymorphic. When you call new Dog(), you always get a Dog constructor — there's no dynamic dispatch for constructors.
Q12: How does polymorphism enable the Open/Closed Principle? With polymorphism, you can add new subclasses without modifying existing code. A method accepting Shape works with any new shape subclass (Circle, Triangle, etc.) without changes. The code is "open for extension" (new shapes) but "closed for modification" (existing code unchanged).
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Polymorphism in Java.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, oops, polymorphism, polymorphism in java
Related Java Master Course Topics