How do I call a parent constructor using super()?

← Constructor Delegation · Ref: Q581

Use super() as the first statement in a child class constructor to call the parent class constructor. This ensures the parent is properly initialized before the child adds its own state.

BASIC SUPER() CALL

Call super() with arguments matching a parent constructor:

  Child()
    -> name as String, age as Integer
    super(name)  //calls Parent(String) constructor
    this.age: age

MUST BE FIRST STATEMENT

super() must be the first statement in the constructor body (E05050). No code can execute before the parent is initialized.

REQUIRES EXPLICIT PARENT

super() is only valid when the class explicitly extends another class. Using super() without an explicit parent produces E05040.

PARAMETER PASSING

Pass the appropriate arguments to match the parent constructor:

  ChildClass()
    -> a as String, b as Integer
    super(a)  //passes 'a' to parent constructor

See Q580 for this() delegation. See Q582 for delegation order. See Q583 for this() vs super() restrictions. See Q584 for missing super() call.

Example

defines module qa.constructor.superdelegation

  defines class

    //Parent class: must be open for extension
    Entity as open
      entityName <- String()

      Entity()
        -> entityName as String
        this.entityName: entityName

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

      default operator ?

    //Child calls super() to initialize parent
    Person extends Entity as open
      personAge <- 0

      Person()
        ->
          entityName as String
          personAge as Integer
        super(entityName)
        this.personAge: personAge

      personAge() as pure
        <- rtn as Integer: personAge

      default operator ?

    //Grandchild also uses super()
    Employee extends Person
      role <- String()

      Employee()
        ->
          entityName as String
          personAge as Integer
          role as String
        super(entityName, personAge)
        this.role: role

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

      default operator ?

  defines program

    SuperDelegationDemo()
      stdout <- Stdout()

      entity <- Entity("Base")
      stdout.println(`Entity: ${entity.entityName()}`)

      person <- Person("Alice", 30)
      stdout.println(`Person: ${person.entityName()}, age ${person.personAge()}`)

      emp <- Employee("Bob", 25, "Developer")
      stdout.println(`Employee: ${emp.entityName()}, age ${emp.personAge()}, role ${emp.role()}`)

Common mistakes

E05050 — The super() call must be the very first statement in the constructor body. No field assignments can appear before the parent is initialized. See ek9 -h E05050 for details.

Incorrect:

Person()
        ->
          entityName as String
          personAge as Integer
        this.personAge: personAge
        super(entityName)

Correct:

Person()
        ->
          entityName as String
          personAge as Integer
        super(entityName)
        this.personAge: personAge

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

stdout.println(entity.entityName().toUpperCase())

Correct:

stdout.println(`Entity: ${entity.entityName()}`)
Other ways to ask this
  • How does super() work in EK9 constructors?
  • How do I initialize the parent class in a constructor?
  • What is super() in a constructor?

Coming from another language?

Java: super() must be first statement, implicit if parent has no-arg constructor. Python: super().__init__() can be called anywhere. Kotlin: primary constructor delegates via super in class header. C#: base() constructor chaining. EK9: super() must be first statement, E05050 if not, E05040 if no explicit parent.

Keywords: E05050, initialize, constructor, super, E05040, constant, parent, first, delegation, this