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 inside a regular method raises E05060. The same misuse in a property initialiser is reported as E05070 (this) or E05080 (super), and in a function as E05070 (this) or E50020 (super).

EK9 distinguishes the CALL syntax from the member-ACCESS syntax:
- `this()` calls another constructor of this class (constructors only)
- `super()` calls the parent constructor (constructors only)
- `this.x` accesses a member of this instance (anywhere in the class)
- `super.x` accesses 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

#!ek9
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: E05060, access, call, constructor, delegation, dot, method, super, this