Can I use both this() and super() in the same constructor?

← Constructor Delegation · Ref: Q583

No. A constructor can use either this() or super(), but not both. Since delegation must be the first statement, only one delegation call is possible per constructor.

THE RULE

A constructor body can contain at most one delegation call: either this() or super(), never both. E05060 covers the use of this()/super() outside constructors; in practice, the first-statement rule (E05050) prevents having both.

CORRECT PATTERN: SEPARATE CONSTRUCTORS

Use separate constructors for different delegation paths:

  Child()
    -> name as String
    this(name, 0)          // this() delegation
  Child()
    -> name as String, count as Integer
    super(name)            // super() delegation
    this.count: count

The one-arg constructor delegates to the two-arg constructor via this(), and the two-arg constructor delegates to the parent via super(). Each constructor has exactly one delegation target.

See Q580 for this() delegation. See Q581 for super() delegation. See Q582 for delegation order. See Q585 for field initialization vs delegation.

Example

defines module qa.constructor.notboth

  defines class

    Animal as open
      species <- String()

      Animal()
        -> species as String
        this.species: species

      species() as pure
        <- rtn as String: species

      default operator ?

    //Correct: this() and super() in SEPARATE constructors
    Pet extends Animal
      petName <- String()

      //This constructor uses this() delegation
      Pet()
        -> petName as String
        this(petName, "Unknown")

      //This constructor uses super() delegation
      Pet()
        ->
          petName as String
          species as String
        super(species)
        this.petName: petName

      petName() as pure
        <- rtn as String: petName

      default operator ?

  defines program

    NotBothDemo()
      stdout <- Stdout()

      //Uses this() path
      pet1 <- Pet("Buddy")
      stdout.println(`${pet1.petName()} is a ${pet1.species()}`)

      //Uses super() path directly
      pet2 <- Pet("Max", "Dog")
      stdout.println(`${pet2.petName()} is a ${pet2.species()}`)

Common mistakes

E05050 — A constructor can use either this() or super(), but not both. Since delegation must be the first statement, only one delegation call is possible per constructor. See ek9 -h E05050 for details.

Incorrect:

Pet()
        -> petName as String
        this(petName, "Unknown")
        super("Cat")

Correct:

Pet()
        -> petName as String
        this(petName, "Unknown")

E05050 — The super() delegation must be the first statement in the constructor body. Field assignments cannot appear before it. See ek9 -h E05050 for details.

Incorrect:

Pet()
        ->
          petName as String
          species as String
        this.petName: petName
        super(species)

Correct:

Pet()
        ->
          petName as String
          species as String
        super(species)
        this.petName: petName
Other ways to ask this
  • What is E05060 this and super together?
  • Why can't I call both this() and super()?
  • Can a constructor delegate to both this() and super()?

Coming from another language?

Java: same rule, cannot have both this() and super(). Kotlin: primary constructor handles implicit super. C#: same rule, choose this() or base(). EK9: same rule, one delegation per constructor.

Keywords: super, constant, both, this, E05060, constructor, delegation, mutual, exclusive