super Keyword
Extending, Not Just Replacing, Inherited Behavior
Overriding a method (Lesson 18.1) completely replaces the superclass's version — but often a subclass wants to run the original logic too, and add something on top of it, rather than throwing it away entirely. super.method() calls the superclass's version of a method explicitly, from inside an override:
public class Subsystem
{
@Override
public String toString() { return "Subsystem"; }
}
public class Intake extends Subsystem
{
@Override
public String toString()
{
return super.toString() + " (Intake)"; // runs Subsystem's version first, then extends it
}
}
super has two distinct uses, both already introduced separately: super(...), which must be the first line of a constructor and calls a superclass constructor (Lesson 17.2); and super.method(), which calls a superclass method from anywhere inside a subclass method body.
How Method Lookup Actually Works
Every object remembers the actual class it was created with. A method call on that object starts looking there first; if the method isn't found in that exact class, Java searches up the chain — parent, grandparent, and so on — until it finds a match (which it always will, or the code wouldn't have compiled in the first place).
public class Subsystem
{
public void periodic() { System.out.println("Subsystem periodic"); }
}
public class Climber extends Subsystem
{
@Override
public void periodic()
{
super.periodic(); // explicitly runs Subsystem's version first
System.out.println("Climber periodic"); // then adds Climber's own behavior
}
}
Calling climberInstance.periodic() starts in Climber.periodic(); when execution reaches super.periodic(), it runs Subsystem.periodic(), then returns to finish the rest of Climber.periodic()'s body.
A Subtlety: super Only Affects the One Call It's Written On
super.someMethod() only changes which version of that specific call runs — it doesn't change how any other method call inside the same method resolves. Any call made without super (an unqualified call, or one through this) still dispatches based on the object's actual runtime type, even from inside inherited code. This is why a super.methodOne() call that internally calls another method still ends up running the subclass's override of that other method, not the superclass's — the override "wins" everywhere except the one spot super explicitly overrides it.
Common Pitfalls
- Forgetting
super.method()must be called explicitly — it never happens automatically the waysuper()does for constructors. Overriding a method completely discards the superclass's version unless the override callssuper.method()itself. - Confusing the two
superforms.super(...)(no method name) only ever calls a constructor, and only as a constructor's first line;super.method()calls a named method, and can appear anywhere inside a method body. - Assuming
super.method()changes every call inside that method to use the superclass's versions. It only affects the one call written withsuper— any other method call inside that same superclass method still resolves against the object's real runtime type.
Key Takeaways
super.method()explicitly calls the superclass's version of a method, letting a subclass extend rather than fully replace inherited behavior.- Method lookup starts at the object's actual class and searches upward through its ancestors until a match is found.
super(...)(constructors) andsuper.method()(methods) are two distinct, unrelated uses of the same keyword.- A
super.method()call only affects that one call — any other unqualified method call inside still dispatches to the object's real runtime type.
Derived from csawesome-2026: unit-5-inheritance-optional/5.04-super-keyword.md (CSA 5.4)
Deck context: mechacoder-test/src/lessons/java-2.js, slide 5 ("Polymorphism: Many Forms")