Concepts / Using 'this' as a Constructor Call

Using 'this' as a Constructor Call

Constructors are not inherited, so a subclass has to define its own constructors, and if it defines none the computer provides a default constructor with no parameters.

  • Programming
Interactive lab

Try it: Inheritance and Method Lookup

How a subclass inherits from its parent, how Python finds an attribute by walking the instance, then the class's method resolution order up to object, how overriding and super() work, why the same call does different things on different objects (polymorphism), and what isinstance / issubclass check.

How it works

  1. class Dog(Animal) gives Dog the MRO Dog → Animal → object; Puppy(Dog) gives Puppy → Dog → Animal → object.
  2. obj.name searches obj.__dict__, then each class of type(obj).__mro__ in order; the first class that defines the name wins, so a subclass method overrides the parent's.
  3. super().method() starts the search in the class after the one the current method was defined in, e.g. to run the parent's __init__.
  4. Calling the same method on a list of different objects runs each object's own version (polymorphism).
  5. isinstance(obj, C) is True when C is in type(obj).__mro__; if no class has the name, Python raises AttributeError.

Default run (63 steps): Ready: Animal, Dog, Cat and Puppy, then the statements you picked. Each attribute is searched along the class's MRO. … Finished. Printed: Rex the dog says Woof / Tom the cat says Meow / Bo the dog says Woof! / True / Puppy / Dog / Animal / object.

Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Single inheritance only (the lab's MRO code is Python's C3 algorithm, but no class here has two parents).

Educational simulation

Loading the simulation…

Predicting What Happens to a Subclass Constructor

When you learn inheritance, it is tempting to assume that a subclass gets everything its superclass has. A subclass does inherit fields and methods, so it seems natural that it would inherit the ways of building an object as well. That belief feels reasonable, and it leads to confusion the first time code does not behave the way you expected. This article traces what really happens when a subclass constructor is run, and it uses the source's own scenario of a Shape superclass and a Circle subclass to show where the rules bite.

What do you think happens?

The superclass Shape has only one constructor, and that constructor takes a String. The subclass Circle has its own constructor, but that constructor does not call super. Does this compile?

  • Yes, Circle inherits Shape's String constructor and it is used automatically

  • No, the compiler reports a syntax error because Shape has no no-parameter constructor for the missing super call

Reveal answer
Answer:

No, the compiler reports a syntax error.

Constructors are not inherited, so Circle does not receive Shape's String constructor. Because Circle's constructor has no explicit super call, Java tries to call the superclass constructor that takes no parameters. Shape has none, so the compiler reports a syntax error.

Constructors Are Not Inherited

Methods and constructors are treated differently when a class is extended. When you extend a class to form a subclass, the subclass inherits the superclass's fields and methods, but the constructors of the superclass do not become part of the subclass. If you want constructors in the subclass, you have to define new ones from scratch. A constructor is the code that builds an object, and each class is responsible for building its own objects. The subclass therefore has to supply its own constructors.

There is a second rule that affects every new class. If you do not define any constructor in the subclass, the computer creates a default constructor for you, and that default constructor takes no parameters. This default exists only when you have written no constructor at all. Once you define any constructor of your own in the subclass, the automatic default is no longer supplied, so the constructors you wrote are the only ones available for that subclass.

Tracing a Circle Construction

Consider a Shape superclass that stores a name and a Circle subclass that stores a radius. The Circle constructor first hands the name to the Shape constructor, then stores its own radius. The sequence below shows the order of events when new Circle is run. Notice that the Circle constructor pauses at its first statement, the super call, while the Shape constructor does its work.

Circle constructorstartsfirst statement is supersuper(name) callpasses name upwardShape constructorbodystores the nameRest of Circle bodystores the radiusShape constructorfinishescontrol returnsCircle constructorfinishesrunscallscompletesreturnscompletes
When new Circle(name, radius) runs, which constructor body executes first, how does control pass up to the Shape constructor, and in what order do the bodies finish?

Read the diagram from top to bottom. The Circle constructor starts, but its first statement is the super call, so the Shape constructor body runs next with the name argument. When the Shape constructor finishes, control returns to the Circle constructor, which then runs its remaining statements. The superclass work always comes first, because the super call must be the first statement in the subclass constructor. The source describes this same order: the superclass constructor runs, control returns, and then the subclass constructor completes the rest of its work.

Passing Arguments with super

The special keyword super lets a subclass constructor call a constructor of its superclass. The call is written as the word super followed by a parenthesized list of arguments, such as super(3,4);. The arguments you pass are matched to the parameters of one of the superclass constructors, so the values travel from the subclass constructor's call into the superclass constructor's parameters, where they can be used to set the superclass's fields.

java
Notes on the code
  • Shape has one constructor that takes a String and stores it in name
  • Circle's constructor takes both a name and a radius
  • super(circleName) is the first statement and passes the name up to Shape
  • radius = r runs after the superclass constructor has finished
Worked example

Constructing a Circle with a Name and Radius

Trace new Circle("ring", 2.5) using the Shape and Circle classes above.

  1. 1
    Circle constructor receives the arguments

    circleName becomes "ring" and r becomes 2.5.

  2. 2
    super(circleName) runs first

    This must be the first statement, so Java passes "ring" to the Shape constructor before anything else in Circle runs.

  3. 3
    Shape stores the name

    The Shape constructor sets its name field to "ring" through its parameter shapeName.

  4. 4
    Circle finishes its own work

    Control returns to Circle, which sets radius to 2.5.

Result

A Circle object whose inherited name field is "ring" and whose radius field is 2.5.

Notice that the super call looks like a method call, and that can be misleading. The source is clear that super is not a subroutine. Constructors cannot be called the way ordinary subroutines are called, and the super construct is valid only in this one circumstance: as the first statement inside a constructor.

What Happens When super Is Missing

Suppose a subclass constructor does not call super at all. The source says that Java then calls the superclass constructor that has no parameters, and it does so automatically. The source adds a second half to this rule that matters a great deal. If the superclass has no such no-parameter constructor, the compiler treats the missing call as a syntax error. The flowchart traces the decision the compiler makes at this point.

Subclassconstructor beginsExplicit super callwritten?Run super(args) aswrittenCompiler insertssuper()Remaining statementsrunSuperclass hasno-parameterconstructor?Syntax error reportedyesnoyesno
When a subclass constructor has no explicit super call, what does the compiler insert, and at which step does it fail if the superclass has no no-parameter constructor?
java
Notes on the code
  • Shape has only a constructor that takes a String, so it has no no-parameter constructor
  • Circle's constructor has no explicit super call
  • The compiler would need to insert super() here, which Shape cannot satisfy
  • This code does not compile, so the compiler reports a syntax error

Mistakes Beginners Make with super

  • Common mistake

    Assuming the subclass inherits the superclass constructors

    What it looks like

    Writing new Circle("ring") when Circle defines no constructor taking a String, expecting Shape's String constructor to be available.

    Why it fails

    Constructors are not inherited. Only fields and methods are passed down to the subclass.

    Do this instead

    Define the constructors the subclass needs, and have them call the superclass constructor with super(...).

  • Common mistake

    Putting setup code before the super call

    What it looks like
    public Circle(String n, double r) { radius = r; super(n); }
    Why it fails

    The source states that the super call must be the very first statement in the subclass constructor, and any statement placed before it breaks this rule.

    Do this instead

    Move super(n) to the first line, then write the remaining assignments after it.

  • Common mistake

    Forgetting that a missing super call is filled in automatically

    What it looks like

    A Circle constructor with no super line, where Shape has only a String constructor.

    Why it fails

    Java inserts a call to the no-parameter superclass constructor. If that constructor does not exist, the compiler reports a syntax error.

    Do this instead

    Write an explicit super call with the matching arguments, or add a no-parameter constructor to the superclass.

  • Common mistake

    Thinking super is an ordinary method that can be called anywhere in the constructor

Practice: Predicting the Result

MEDIUM

Shape has only a constructor that takes a String. A new subclass Square has the constructor public Square(double side) { this.side = side; } with no super line. Will this compile, and what change would make it compile? Explain your answer using the rule about the no-parameter superclass constructor.

Hints
  • Ask first whether Java can find a no-parameter constructor in Shape to insert automatically.
  • Consider two fixes: adding a no-parameter constructor to Shape, or adding an explicit super call with a String argument as the first statement of Square's constructor.
EASY

Write a Rectangle subclass of a Shape superclass whose constructor takes a String. Give Rectangle a constructor that takes a String name and a double width, passes the name up with super as its first statement, and stores the width in its own field.

Hints
  • The first line of the constructor should be a super call with the name argument.
  • Store the width after the super call finishes.

Key Takeaways

  • Constructors are not inherited, so a subclass must define its own constructors, and if it defines none, the compiler supplies a default constructor that takes no parameters.
  • Inside a subclass constructor, super(...) calls a superclass constructor with arguments, and that call must be the very first statement.
  • When no super call is written, Java calls the superclass constructor with no parameters automatically; if that constructor does not exist, the compiler reports a syntax error.
  • The fix is either to add a no-parameter constructor to the superclass or to write an explicit super call that matches one of the superclass constructors.