Method Overriding in Java
super is a special variable used inside a subclass to refer to the object's superclass view, and it remembers only that the object belongs to the superclass of the class being written.
A Prediction Before the Explanation
Many learners meet the word super for the first time and assume it works like a mirror: a reference that sees the whole object, including everything the subclass has added or changed. That belief feels reasonable, because the object really does contain both the subclass and the superclass pieces. This article answers a narrower question. When Java code inside a subclass writes super, what is it allowed to see, and what is it blind to?
Imagine a superclass named Vehicle that has a method start(). A subclass named Truck extends Vehicle and adds its own method named haul(). Inside Truck, a programmer writes super.haul(). Before reading on, decide whether that call should work.
What do you think happens?
Inside Truck, does super.haul() work?
Reveal answer
No. super.haul() does not compile, because super refers only to the superclass view and haul() was added in Truck.
The source explains that super does not know about additions a class makes to its superclass, so it can be used only to refer to methods and variables in the superclass.
The Object Seen Through super
The word super is best understood as a view onto the object, not a view onto the whole object. The source describes it as a reference to the object that contains the method, with one important restriction: it forgets that the object belongs to the class you are writing. It remembers only that the object belongs to the superclass of that class.
Inside Truck, then, the object is seen as a Vehicle and nothing more specific. A single Truck object is one physical object, but the code inside Truck reads it through two different lenses. The subclass lens sees everything Truck declares. The super lens sees only what Vehicle declares.
The diagram shows the two groups side by side. The superclass group is the only group that super can reach. The subclass additions, haul() and the Truck name field, belong to the Truck code's own view. Reading the diagram this way answers the prediction: haul() sits in the subclass group, so super has no path to it.
Why super Exists at All
super is a special variable used inside a subclass to refer to the object's superclass view. It remembers only that the object belongs to the superclass of the class being written, so it can be used only to refer to methods and variables defined in the superclass.
If super can see only the superclass, why does it exist? The source gives the purpose directly: super exists so you can reach things in the superclass that have been hidden by things in the subclass. Hiding happens when a subclass declares something that shares a name with a superclass member. Without super, the superclass version would be out of reach from subclass code, because the subclass's own name would always win.
super.var always refers to the superclass version of var. Its meaning does not depend on what the subclass has done with var, and the same is true of super.method(), which reaches the superclass version of a method.
Hidden Fields and Overridden Methods
Subclasses can change superclass members in two related ways, and super treats them differently in a way worth learning carefully. The two situations are hiding and overriding.
Tracing a Call Through super
When new Truck().show() is called, the output is:
truck
vehicle
Vehicle starting- name inside Truck reads the subclass field, which hides the superclass field
super.namealways reads the superclass field named namesuper.start()runs the Vehicle version ofstart(), even though Truck overridesstart()
truck
vehicle
Vehicle startingThe output shows the same object reached two ways. The first line uses the subclass view and gets the Truck field. The second line uses super and gets the Vehicle field. The third line shows an overridden method reached through super: the call goes to the Vehicle version even though the object's class overrides start().
Following the super.start() Call
The next diagram traces where execution goes when a subclass method calls super.start(). The overriding method calls the superclass version as part of its own work, and then returns control back to itself.
Notice what does not appear in the trace: the Truck version of start() is not called a second time. The call through super names the superclass version directly, so the lookup starts at Vehicle rather than at the subclass. That is the reason super is needed when a subclass wants the superclass behavior as one step of its own method.
Mistakes Beginners Make with super
Common mistake Assuming super can see methods the subclass added
What it looks likeInside Truck, writing super.haul() when haul() is defined only in Truck
Why it failssuper refers only to the superclass view, and it does not know about additions the subclass made.
Do this insteadCall haul() directly, or use the subclass view, because haul() belongs to Truck.
Common mistake Thinking a subclass field replaces the superclass field
What it looks likeDeclaring String name in Truck and expecting super.name to return the Truck value
Why it failsA subclass variable with the same name hides the superclass variable. Both exist in the object.
Do this insteadUse super.name when the superclass version is needed, and plain name when the subclass version is needed.
Common mistake Expecting super.start() to run the subclass version
What it looks likeCalling super.start() from Truck and expecting Truck starting to print
Why it failssuper.start()reaches the superclass method, and the source says overriding does not remove that method.Do this insteadRead super.method() as the superclass version of the method, even when the object's class overrides it.
Common mistake Forgetting that a signature includes the parameter list when deciding whether a method overrides another
Plain Access Versus super Access
| Question | Plain access inside Truck | Access through super inside Truck |
|---|---|---|
| Which field is read? | The Truck field, which hides the Vehicle field | The Vehicle field |
| Which start() runs when called? | The Truck version, if Truck overrides start() | The Vehicle version |
| Can it reach haul()? | Yes, because haul() is defined in Truck | No, super cannot reach additions made by Truck |
| What does it refer to? | The object as the class being written | The object as seen through its superclass |
How plain access and super access differ inside a subclass
The table makes the central distinction concrete. Plain names inside a subclass use the subclass view, which includes everything the subclass declares. super uses the superclass view, which includes only what the superclass declares. For fields, the two lenses give different values. For overridden methods, they run different implementations.
Practice: Predict the Output
Using the Vehicle and Truck classes from the earlier example, suppose a new method is added to Truck: void report() { System.out.println(super.name); System.out.println(name); }. Before running anything, predict the two lines printed when report() is called on a Truck object. Then predict what happens if the line System.out.println(super.haul()); is added to report() instead.
Hints
super.namereaches the superclass field, so the Vehicle value should print- Plain name reads the Truck field inside Truck
- super can reach only members defined in Vehicle, and
haul()is defined in Truck
Key Takeaways
- Inside a subclass, super refers to the object's superclass view and can reach only members defined in the superclass.
- super cannot see methods or variables that the subclass added, so
super.haul()fails whenhaul()is defined only in Truck. - A subclass variable with the same name hides the superclass variable, and super.var always reaches the superclass version.
- A subclass method with the same signature overrides the superclass method, and
super.method()still runs the superclass version. - The subclass view and the super view are two lenses on one object, and knowing which lens a line of code uses explains its result.