Why can't I call this() or super() inside a regular method?

← Constructor Delegation · Ref: Q1311

this() and super() are constructor delegation CALLS. They are only valid as the first statement inside a constructor body, where they delegate to another constructor of the same class (this(...)) or to the parent constructor (super(...)). Using them as a call anywhere else - inside a regular method, a property initializer, or a function - raises E05060.

EK9 distinguishes the CALL syntax from the member-ACCESS syntax:

  this()  = call another constructor of this class (constructors only)
  super() = call the parent constructor (constructors only)
  this.x  = access a member of this instance (anywhere in the class)
  super.x = access a parent member (anywhere in the class)

If you wanted to read or assign a member from inside a method, use the DOT form (this.field or super.method()). If you genuinely wanted to delegate, move the call into a constructor as its first statement.

See Q580 for this() delegation. See Q581 for super() delegation. See Q582 for delegation order (E05050).

Example

defines module qa.constructor.delegationscope

  defines class

    Animal as open
      species <- String()

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

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

      default operator ?

    //Pet uses super() correctly - only inside a constructor, as the first statement.
    Pet extends Animal
      petName <- String()

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

      //CORRECT: a regular method uses DOT access (this.petName), never the
      //delegation CALL super(...). Methods cannot re-run a constructor.
      rename()
        -> newName as String
        this.petName: newName

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

      default operator ?

  defines program

    DelegationScopeDemo()
      stdout <- Stdout()

      pet <- Pet("Buddy")
      stdout.println(`${pet.petName()} is a ${pet.species()}`)

      pet.rename("Max")
      stdout.println(`Renamed to ${pet.petName()}`)

Common mistakes

E05060 — super(...) is a constructor delegation CALL and may only appear as the first statement of a constructor, so calling it inside the rename() method raises E05060. A regular method cannot re-run the parent constructor. To touch members from a method use the DOT access form (this.petName or super.someMethod()); to delegate, move the call into a constructor. See ek9 -h E05060 for details.

Incorrect:

rename()
        -> newName as String
        super("Reset")
        this.petName: newName

Correct:

rename()
        -> newName as String
        this.petName: newName
Other ways to ask this
  • What triggers E05060 this()/super() outside a constructor?
  • Why does EK9 reject super() in a normal method?
  • How do I call a parent member from a method without super()?

Coming from another language?

Java: this()/super() are also constructor-only and the compiler rejects them in methods, but the error is generic. Kotlin: super.method() is the access form and there is no this() call in methods. C#: this()/base() are constructor-initializer-only. EK9: compile-time error E05060 with an explicit hint to switch from CALL syntax () to ACCESS syntax (.), or move the delegation into a constructor.

Keywords: super, access, call, this, E05060, constructor, method, delegation, dot