Java Polymorphism
One contract. Different behavior.
Read this topic in தமிழ் ↗.
By the end of this lesson, you can…
- Explain the key idea behind Polymorphism.
- Read and run a complete example, then predict what changes.
- Recognize the topic-specific mistake discussed below.
Understand the idea
An overridden instance method is selected using the runtime object, even when a variable has a superclass or interface type. This lets calling code use a common contract while individual implementations provide their own behavior.
Explore the details
Java Polymorphism
Polymorphism means "many forms". The same method name behaves differently depending on which object calls it — each subclass provides its own implementation.
Use @Override when a child class replaces a parent method. It tells Java (and readers) that this method intentionally replaces the parent version — and the compiler will catch typos in the method signature.
Polymorphism in Action — List of Animals
The real power of polymorphism is using a parent-type reference to hold any subclass object. You can loop over a list and call the same method — Java automatically calls the right version for each object.
import java.util.ArrayList;
ArrayList<Animal> animals = new ArrayList<>();
animals.add(new Dog());
animals.add(new Cat());
animals.add(new Dog());
for (Animal a : animals) {
a.sound(); // Java calls Dog.sound() or Cat.sound() automatically
}
// Output:
// Woof!
// Meow!
// Woof!Types of Polymorphism
| Type | When resolved | Mechanism | Example |
|---|---|---|---|
| Compile-time (static) | At compile time | Method overloading | area(r) vs area(w, h) |
| Runtime (dynamic) | At run time | Method overriding (@Override) | a.sound() dispatches to Dog or Cat |
Why Polymorphism Matters
- Extensibility — add a new
Birdsubclass and existing loop code still works without changes - Cleaner code — one variable type (
Animal) handles all subtypes - Loose coupling — callers don't need to know the exact subclass
- Open/Closed Principle — code is open for extension but closed for modification
A complete runnable example
This complete Main.java program focuses on the lesson idea. Reference fragments above may demonstrate individual statements; this example includes the imports, entry point, and supporting types it needs.
public class Main {
public static void main(String[] args) throws Exception {
Animal[] pets = {new Dog(), new Cat()};
for (Animal pet : pets) pet.sound();
}
}
class Animal { void sound() { System.out.println("Animal"); } }
class Dog extends Animal { @Override void sound() { System.out.println("Woof"); } }
class Cat extends Animal { @Override void sound() { System.out.println("Meow"); } }Predict first. Then reveal the expected output / வெளியீடு
Woof Meow
The output shown was checked by running this complete example. Trace the executed statements in order, then compare with your run.
Change it. Run it. Understand it.
Load this lesson example into the editor. Change one value or statement, predict the result, then press RUN to execute Java.
Powered by OneCompiler. Code you run is sent to OneCompiler for execution. For Scanner examples, supply input in the editor I/O panel; for file examples, files exist in its execution environment.
Make it your own
Practice challenge
Add another Dog to the array and predict the output order.
Reveal the answer and reasoning / விடை
The sequence is Woof, Meow, Woof. The loop calls the same method name on three runtime objects.
One mistake to avoid: Fields and static methods do not use the same dynamic dispatch rules as overridden instance methods.
Your learning checkpoint
- Explain the example without reading the output first.
- Make the change requested in the practice task.
- Describe why the result changed—or why compilation failed.
Ready to move on? Follow the next lesson in course order, or return to the curriculum to review a prerequisite.