About Us Contact Us Write for Us Advertise
Home > Java > Polymorphism in Java: One Method, Many Forms Explained Simply
Java

Polymorphism in Java: One Method, Many Forms Explained Simply

Learn polymorphism in Java the easy way — the third pillar of OOP. See how the same method call behaves differently per object, with dynamic dispatch explained by example.

Shiv Pandey
Shiv Pandey
Sep 21, 2026 | 4 views
Polymorphism in Java: One Method, Many Forms Explained Simply

Polymorphism is a big, intimidating-looking word — but the idea behind it is beautifully simple. It comes from Greek: "poly" (many) + "morph" (forms), so it means "many forms." In Java, it's the ability for the same method call to behave differently depending on the object it's acting on. It's the third pillar of OOP, and it builds directly on the inheritance and overriding you just learned.

The core idea

Think of a single command: "make a sound." Give that command to a dog and you get a bark; give it to a cat and you get a meow; give it to a cow and you get a moo. Same command, different results depending on the animal. That's polymorphism — one interface, many behaviours.

Setting it up with overriding

We start with a parent class and let each child override a method its own way:

class Animal {
    void makeSound() {
        System.out.println("Some generic sound");
    }
}

class Dog extends Animal {
    @Override void makeSound() { System.out.println("Woof!"); }
}

class Cat extends Animal {
    @Override void makeSound() { System.out.println("Meow!"); }
}

The magic: a parent type holding a child object

Here's the key move. Because a Dog is an Animal, you're allowed to store a Dog object in an Animal variable. And when you call the method, Java runs the actual object's version — not the variable's type version:

Animal a1 = new Dog();   // an Animal variable holding a Dog
Animal a2 = new Cat();   // an Animal variable holding a Cat

a1.makeSound();   // "Woof!"  — runs Dog's version
a2.makeSound();   // "Meow!"  — runs Cat's version

Even though both variables are typed Animal, each call dispatches to the real object's overridden method. Java figures out the correct method at runtime — this is called dynamic dispatch, and it's the engine behind polymorphism.

Why this is powerful: one loop for everything

The payoff is code that works with a whole family of types without knowing or caring which specific one it has. Watch how one loop handles every animal:

Animal[] zoo = { new Dog(), new Cat(), new Dog() };

for (Animal animal : zoo) {
    animal.makeSound();   // Woof! Meow! Woof! — each does its own thing
}

Add a new Cow class tomorrow and this loop needs zero changes — it already handles it. That flexibility is why polymorphism sits at the heart of good software design.

Two flavours of polymorphism (a note)

Type What it means
Runtime (overriding) Same method, different classes — the main kind, shown above
Compile-time (overloading) Same method name, different parameters in one class (e.g. add(int,int) vs add(double,double))

You've actually met overloading already — with constructors. When people say "polymorphism," they usually mean the runtime/overriding kind, because that's where the real design power lies.

Polymorphism was the concept that finally made OOP feel elegant to me rather than just organised. The first time I wrote a single loop that correctly handled a dozen different object types — each behaving in its own way, with no giant if-else chain — it genuinely felt like magic. It's the idea that lets large programs stay flexible as they grow, and you'll see it everywhere in professional Java and frameworks like Spring.

Key takeaways

  • Polymorphism = "many forms": the same method call behaves differently per object.
  • A parent-type variable can hold a child object; the object's overridden method runs (dynamic dispatch).
  • This lets one piece of code (like a loop) work across a whole family of types.
  • Runtime polymorphism uses overriding; overloading is the compile-time cousin.

← Previous: Lesson 15 — Inheritance in Java
Next: Lesson 17 — Abstraction & Interfaces →

Related Articles

Arrays in Java: Storing and Looping Through Many Values
Java

Arrays in Java: Storing and Looping Through Many Values

Java Methods Explained: Reusable Code with Parameters and Return Values
Java

Java Methods Explained: Reusable Code with Parameters and Return Values

Java Loops Explained: for, while and do-while (with Examples)
Java

Java Loops Explained: for, while and do-while (with Examples)

Operators in Java Explained (with Examples)
Java

Operators in Java Explained (with Examples)