Polymorphism in Java
Press "play" on a phone, a laptop or a smart TV and each one plays in its own way, yet you pressed the same button. Polymorphism ("many forms") is that idea in code: one method call, many behaviors, decided by the object that receives it. It's the third pillar of OOP, and it's the reason a well-designed program can grow new features without rewriting the parts that already work.
One Call, Many Behaviors
public class Alerts {
static class Notifier {
String send(String to) { return "Generic alert to " + to; }
}
static class SmsNotifier extends Notifier {
@Override
String send(String to) { return "SMS to " + to; }
}
static class EmailNotifier extends Notifier {
@Override
String send(String to) { return "Email to " + to; }
}
static class AppNotifier extends Notifier {
@Override
String send(String to) { return "App push to " + to; }
}
public static void main(String[] args) {
Notifier[] channels = {
new SmsNotifier(), new EmailNotifier(), new AppNotifier()
};
String[] people = {"Navika", "Srihitha", "Advitha"};
for (int i = 0; i < channels.length; i++) {
System.out.println(channels[i].send(people[i]));
}
}
}SMS to Navika
Email to Srihitha
App push to AdvithaHow it works
- Every element of
channelshas the declared typeNotifier. - Each element refers to a different kind of object, and each kind overrides
send. - The loop body is one line,
channels[i].send(...), but the JVM runs thesendof the actual object each time.
Try it yourself: add a WhatsAppNotifier and put one in the array. Notice that the loop doesn't change at all.
Two Kinds of Polymorphism
| Compile-time polymorphism | Runtime polymorphism | |
|---|---|---|
| Achieved by | Method overloading | Method overriding |
| Who decides which method runs | The compiler, from the argument types | The JVM, from the object's actual class |
| Also called | Static polymorphism, early binding | Dynamic polymorphism, late binding, dynamic method dispatch |
| Example | println(int) vs println(String) | channel.send(...) above |
Both get their own lessons in this chapter. When people say "polymorphism" without a qualifier, they usually mean the runtime kind.
Adding Types Without Editing Old Code
Without polymorphism, the loop above would need an if for every channel:
if (channel is SMS) { ...send an SMS... }
else if (channel is Email) { ...send an email... }
else if (channel is App) { ...send a push... }
// every new channel means editing this code againWith polymorphism, adding a new channel means adding a class, not editing old code. Code that works with Notifier keeps working with any notifier written in the future. This idea is the open-closed principle (see "SOLID Principles in Java"): open for extension, closed for modification.
Common Mistakes
Calling a child-only method through a parent reference. Notifier n = new SmsNotifier(); n.smsOnlyMethod(); doesn't compile. The variable's type limits what you may call (see "Upcasting and Downcasting").
Thinking fields are polymorphic. Only instance methods are. Fields and static methods follow the variable's type (see "Can Static, Private and Final Methods Be Overridden").
Using instanceof chains where an overridden method would do. If every subclass needs its own behavior, put a method in the parent and override it.
Interview Corner
What is polymorphism in Java?
Polymorphism means one interface with many implementations: the same method call behaves differently depending on the object that receives it. Java supports compile-time polymorphism through method overloading, resolved by the compiler from argument types, and runtime polymorphism through method overriding, resolved by the JVM from the object's actual class. A parent-type reference can hold any subclass object, and calls run the subclass's overriding method.
How does polymorphism help in real projects?
It lets code depend on a general type instead of specific classes. New behavior is added by writing a new subclass or interface implementation, without editing the code that uses the general type. That reduces if-else chains and keeps changes local.
Practice
- Easy: Create
Animalwithsound(), andDog,CatandCowthat override it. Print every sound from anAnimal[]array. - Harder: Create
Discountwithapply(double amount), andFestivalDiscount(10% off) andFlatDiscount(Rs. 200 off). Apply each to Rs. 2,000 in one loop.
Key Takeaways
Was this tutorial helpful?