MA-JAVA0 · Module 15
Class inheritance, super, and overriding
Topics: extends · super · @Override · Substitution
Overview
Session 15 — Class inheritance, super, and overriding
Subclassing lets you say “this type is a specialised kind of that type.” You reuse fields and behaviour from a superclass, specialise with extra state, and replace individual methods through overriding while still calling super when you want layered behaviour. This session separates overriding (runtime choice) from overloading (compile-time choice) and shows why @Override belongs on every replacement method.
Time: about 95 minutes.
Concepts
1. The extends keyword
A class may subclass exactly one other class (Java has single inheritance for implementation):
public class AlarmClock extends Clock {
// AlarmClock is-a Clock; inherits visible members
}
The subclass inherits non-private members of the superclass. Constructors are not inherited—you must route initialization through super(...) or an implicit default super-call.
2. Constructors chain with super(...)
If you write no constructor, the compiler inserts a default that calls super(). If you write a constructor, the first statement must be this(...) or super(...):
public AlarmClock(String zone, int volume) {
super(zone); // Clock(String) runs first
this.volume = volume;
}
If the superclass has no zero-arg constructor, every subclass constructor must explicitly call a visible super(...).
3. Overriding and @Override
Overriding replaces a runtime-selected implementation when the receiver’s dynamic type is the subclass:
@Override
public String summary() {
return super.summary() + " vol=" + volume;
}
Always annotate with @Override. If the superclass method is renamed, your “override” without the annotation can silently turn into an overload or a dead method—@Override makes that a compile error.
4. Overloading is not overriding
Two methods in the same class (or inherited visible) with the same name but different parameter lists are overloads. The compiler picks by static types of arguments at the call site. Overriding depends on @Override-compatible signatures and dynamic dispatch on the object’s actual class.
5. protected visibility
protected members are visible to subclasses even in other packages (unlike package-private). Use when shared hooks are meant for extension, but avoid exposing deep internals that break encapsulation across the whole hierarchy.
6. instanceof and safe narrowing
After if (obj instanceof AlarmClock ac) (pattern match Java 16+), ac is narrowed inside the block. Older style: cast after instanceof check. Prefer polymorphic designs that rarely need casts.
7. Design smell: deep trees
Very deep inheritance chains become hard to reason about. Favour composition (hold a helper object) when “is-a” feels forced; use inheritance when substitutability is genuinely required everywhere a superclass is accepted.
Examples
Example A — minimal hierarchy
public class Clock {
private final String zone;
public Clock(String zone) {
this.zone = zone;
}
public String tickLabel() {
return "tick@" + zone;
}
}
public class AlarmClock extends Clock {
private final int volume;
public AlarmClock(String zone, int volume) {
super(zone);
this.volume = volume;
}
@Override
public String tickLabel() {
return super.tickLabel() + "(alarm vol=" + volume + ")";
}
}
Calling tickLabel() on an AlarmClock reference executes the subclass body; storing it in a Clock variable still dispatches to AlarmClock at runtime.
Example B — overload vs override side by side
public class Ledger {
public void record(String note) { /* ... */ }
public void record(String note, int amount) { /* overload */ }
}
public class AuditedLedger extends Ledger {
@Override
public void record(String note) {
super.record("[audit] " + note);
}
// record(String, int) inherited unless also overridden
}
The two-argument record is an overload in the superclass. The subclass overrides only the one-argument form.
Practice check — inheritance, super, and overriding
Multiple-choice check from the Matheion app lesson. Pick an answer for each question, then submit.
1.`extends` means…
2.What does `@Override` help with?
3.`super.method()` calls…
4.Substitution (intro level) means…
5.Overriding differs from overloading because overriding…