Inheritance and Constructors
Constructors Are Never Inherited
A subclass inherits its superclass's public methods and fields, but it does not inherit constructors, and it can't directly touch the superclass's private fields. Yet those inherited private fields still need to be properly set up before anything uses them — so how does a subclass initialize state that belongs to its superclass?
The super(...) Call
The keyword super, used like a method call, runs the superclass's constructor code in the context of the object already being built:
public class Subsystem
{
private String name;
public Subsystem(String name) { this.name = name; }
public String getName() { return name; }
}
public class Intake extends Subsystem
{
private boolean hasGamePiece;
public Intake(String name)
{
super(name); // runs Subsystem's constructor, setting the private `name` field
hasGamePiece = false; // Intake's own field
}
}
super(name) isn't creating a second object — it's the one and only way to run Subsystem's own initialization logic for the object currently under construction. Without it, name would never get set, since Intake has no direct access to that private field to assign it itself.
The Implicit super() Call
If a constructor doesn't start with an explicit super(...) call, Java automatically inserts a no-argument super() call for you. That only works if the superclass actually has a no-argument constructor — if it doesn't, any subclass constructor must explicitly call super(...) with arguments matching a constructor that does exist, or the code won't compile.
The Chain Bottoms Out at Object
Whether called explicitly or inserted implicitly, every chain of super calls eventually reaches java.lang.Object's own no-argument constructor — the one class with no superclass of its own (Lesson 17.4). From there, construction "unwinds": Object's constructor logic runs first, then each class going back down the hierarchy, ending with whichever class was actually instantiated. By the time your own constructor's body runs, every inherited field further up the chain has already been properly initialized.
Intake intake = new Intake("Front Intake");
// Order of execution: Object() -> Subsystem(String) -> Intake(String)
Common Pitfalls
- Trying to assign a superclass's private field directly.
this.name = name;insideIntake's constructor doesn't compile ifnameisprivateinSubsystem— onlysuper(name)can reach it. - Forgetting
super(...)must be the first statement. A subclass constructor callingsuper(...)after other statements doesn't compile — it must be the very first line, since the superclass has to finish initializing before the subclass's own code can safely run. - Assuming a no-argument
super()always works. If the superclass has no no-argument constructor (only ones taking parameters), Java can't insert an implicit call — the subclass must explicitly callsuper(...)with matching arguments.
Key Takeaways
- Constructors are never inherited — only a
super(...)call can run the superclass's constructor logic to initialize its own (even private) fields. - If a subclass constructor doesn't call
super(...)explicitly, Java inserts a no-argumentsuper()call automatically — which only works if the superclass has one. - Every construction chain eventually reaches
Object's constructor, which runs first; the subclass's own code only runs after every class above it has finished initializing.
Derived from csawesome-2026: unit-5-inheritance-optional/5.02-inheritance-and-constructors.md (CSA 5.2)