Lesson 3 of 516 minModule progress 0%

Module 8: Object-Oriented Design in Practice

Safe Method Overriding

Override methods safely, keep behavior predictable, and avoid breaking code that uses the parent type.

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

  • Apply Java’s core overriding rules correctly
  • Preserve behavior contracts when overriding
  • Use `@Override` to catch mistakes early

Overriding changes behavior in a subclass, not the method signature contract: Same method name, same parameter list, compatible return type.

Visibility can widen, not narrow: A protected parent method can become public, but a public parent method cannot become protected.

Use @Override every time: It turns accidental overloads into compile errors.

Think about the caller: Code written against the parent type should still work correctly when the child implementation runs.

Runnable examples

An override keeps the same contract

class Animal {
    public void speak() {
        System.out.println("Some sound");
    }
}

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

Expected output

A Dog can replace an Animal reference and still satisfy the same `speak()` contract.

Common mistakes

Changing the parameter list and thinking the method was overridden

That creates an overload, not an override. Keep the same parameters for overriding.

Returning a completely unrelated type

The return type must be the same or covariant where Java allows it.

Mini exercise

Create a `PaymentMethod` base class and override `pay()` in `CardPayment` and `CashPayment`.

Summary

  • Overriding is about replacing behavior, not redesigning the signature.
  • `@Override` is a safety tool, not decoration.
  • A good override respects the parent contract.

Next step

Next, use polymorphism intentionally instead of writing long `if/else` blocks for each subtype.

Sources used

Advertisement

Lesson check

What does `@Override` help prevent?

Next lesson →