Overriding Methods
What Overriding Is
A subclass inherits all its superclass's public methods unchanged — but it can also override one, replacing the inherited version with its own. Overriding requires matching the superclass method's signature — the same name and the same parameter list — with a return type that is the same as the superclass method's, or a subtype of it (called a covariant return type).
RobotPart (Lesson 17.1) has a general-purpose stop() that only logs a message: public void stop() { log("stopped"); }. Intake overrides it with a version specific to its own rollers:
public class Intake extends RobotPart
{
public Intake(String name) { super(name); }
@Override
public void stop()
{
// Intake's own, specific version replaces RobotPart's
log("rollers off, game piece held");
}
}
@Override is optional but always worth writing — it tells the compiler "I intend to override an inherited method here," and the compiler then checks the signature truly matches. Without it, a typo in the method name (stopp() instead of stop()) would silently create a brand-new, unrelated method instead of overriding anything — with @Override, that same typo becomes a compile error instead of a bug that only shows up at runtime.
Overriding vs. Overloading
These sound similar but are entirely different things. Overriding means the same signature, in a subclass, replacing the superclass's version. Overloading means the same method name with a different parameter list — either in the same class, or added by a subclass alongside the method it inherited. Here RobotPart overloads its own log():
public class RobotPart
{
// ...name field, constructor, getName(), and stop() as in Lesson 17.1
public void log(String msg) { System.out.println("[" + name + "] " + msg); }
// overload — same name, different parameters
public void log(String msg, int code) { log(msg + " (code " + code + ")"); }
}
Two methods can never differ only in return type — that alone doesn't count as a valid overload. And a subclass method with the same name and parameters as an inherited one, but an incompatible return type (for example int where the superclass method returns void), isn't an override either: it's a compile error.
Inherited Getters and Setters Still Apply
A subclass gets its superclass's public getters and setters automatically, and — since the superclass's fields are private — those accessor methods remain the only way to reach them, even from the subclass itself (unless the superclass marks a field protected, Lesson 17.2):
public class Intake extends RobotPart
{
// ...constructor and stop() as above
public void announce()
{
// must go through the inherited getter — direct access to name isn't legal here
System.out.println("Intake online: " + getName());
}
}
Preventing an Override: final
A method declared final can't be overridden: if RobotPart declared public final String getName(), any subclass that tried to write its own getName() would fail to compile. A whole class can be final too, which means it can't be extended at all — String is one, so class MyString extends String doesn't compile. Lesson 23.1 covers final in full.
Common Pitfalls
- Mismatching the signature and expecting an override anyway. Changing the parameter list (even by adding one parameter) makes it an overload, not an override — the original method is still inherited unchanged, sitting alongside the new one.
- Forgetting
@Override. Skipping it doesn't break anything when the signature is right, but it removes the compiler's safety net against typos — always include it when overriding. - Changing only the return type.
public int stop()next to a superclass'spublic void stop()doesn't compile —intisn't compatible withvoid, so it's neither a valid override nor a valid overload.
Key Takeaways
- Overriding replaces an inherited method with a new version in the subclass: same name and parameter list, with a return type that's the same or a subtype (covariant).
@Overrideisn't required, but should always be used — it turns a signature typo into a compile error instead of a silent, unrelated new method.- Overloading is different: same name, different parameter list — in the same class, or added in a subclass — not to be confused with overriding.
- Two methods can never differ only in return type.
- Inherited getters/setters remain the only way to reach a superclass's private fields, even from within the subclass.
- A
finalmethod can't be overridden, and afinalclass (likeString) can't be extended.
Derived from csawesome-2026: unit-5-inheritance-optional/5.03-overriding-methods.md (CSA 5.3)
Deck context: mechacoder-test/src/lessons/java-2.js, slide 5 ("Polymorphism: Many Forms")