Lesson 4 of 518 minModule progress 0%

Module 8: Object-Oriented Design in Practice

Practical Polymorphism

Replace repeated type checks with objects that know how to do their own job.

Author

Java Learner Editorial Team

Reviewer

Technical review by Java Learner

Last reviewed

2026-04-17

Java version

Java 25 LTS

How this lesson was prepared: AI-assisted draft, manually edited for clarity, and checked against current Java documentation and runnable examples.

Learning goals

  • Spot logic that should become polymorphic
  • Push behavior into the right type
  • Keep client code smaller and easier to extend

Condition chains often hide missing polymorphism: If you keep checking type values or using repeated instanceof, your objects may be too passive.

Polymorphism moves decisions into the right class: Each subtype handles its own behavior, and the caller just sends one message.

This makes extension easier: Adding one new subtype usually means one new class, not editing a giant control structure.

Do not overdo it: If there are only two simple cases and the logic is tiny, a straightforward branch may still be fine.

Runnable examples

Each class owns its own discount logic

abstract class Discount {
    public abstract double apply(double price);
}

class StudentDiscount extends Discount {
    @Override
    public double apply(double price) {
        return price * 0.9;
    }
}

class HolidayDiscount extends Discount {
    @Override
    public double apply(double price) {
        return price * 0.8;
    }
}

Expected output

The caller no longer needs an `if` chain to choose discount behavior.

Common mistakes

Keeping a subtype plus a `type` field that duplicates the decision

Pick one design. Polymorphism already encodes the behavior choice.

Using polymorphism for one-off logic that never varies

Only introduce types when they buy you clarity or extensibility.

Mini exercise

Turn a shipping calculator with `if (speed.equals("express"))` branches into polymorphic shipping strategy classes.

Summary

  • Polymorphism is most valuable when behavior varies by type.
  • It reduces caller-side branching.
  • New behavior should ideally mean a new class, not rewriting old code.

Next step

Finish the module by combining abstraction, composition, and polymorphism in one small project.

Sources used

Advertisement

Lesson check

Why does polymorphism often improve maintainability?

Next lesson →