When is an explicit super() call required?
← Constructor Delegation · Ref: Q584
super() is only needed when you want the parent initialised from arguments. If the parent has a no-arg constructor (declared, or the one EK9 synthesises), EK9 implicitly calls it. E05040 fires if you call super() or use super.member in a class without an explicit parent class. E05080 is the 'inappropriate use of super' error, for example super(...) used as a property initialiser.
WHEN SUPER() IS NEEDED
When the parent's only declared constructor takes parameters, EK9 still synthesises a public no-arg constructor for it. A child constructor that omits super() therefore compiles - the implicit super() reaches that no-arg constructor - but the parent's properties are left unset (here entityName). Call super(entityName) to give the parent its value. Only when the parent's no-arg constructor is private is omitting super() a compile error (E07176/E07177).
WHEN SUPER() IS IMPLICIT
If the parent has a no-arg constructor (or a default constructor), and the child constructor does not explicitly call super(), the parent no-arg constructor is called implicitly.
E05040: NO EXPLICIT PARENT
If you call super() in a class that does not explicitly extend another class, the compiler reports E05040.
SUPER MEMBER ACCESS WITHOUT A PARENT
Using the 'super' keyword for member access ('super.entityName()') in a class that does not extend another is also E05040.
E05080: INAPPROPRIATE USE OF SUPER
super(...) written as a property initialiser, for example 'petName as String: super("x")', is reported as E05080.
See Q580 for this() delegation. See Q581 for super() basics. See Q582 for delegation order. See Q587 for multi-level constructor hierarchies.
Example
defines module qa.constructor.missingsuper defines class //Parent with required parameter: child MUST call super() NamedEntity as open entityName <- String() NamedEntity() -> entityName as String this.entityName: entityName entityName() as pure <- rtn as String: entityName default operator ? //Child calls super(entityName) so the parent is given its value; //omitting it would still compile but leave entityName unset TaggedEntity extends NamedEntity tag <- String() TaggedEntity() -> entityName as String tag as String super(entityName) this.tag: tag tag() as pure <- rtn as String: tag default operator ? //Parent with default constructor: super() is implicit SimpleBase as open default SimpleBase() baseLabel() as pure <- rtn as String: "simple" default operator ? //Child does not need explicit super() call SimpleDerived extends SimpleBase derivedLabel <- String() SimpleDerived() -> derivedLabel as String //No super() needed: SimpleBase() is called implicitly this.derivedLabel: derivedLabel derivedLabel() as pure <- rtn as String: derivedLabel default operator ? defines program MissingSuperCallDemo() stdout <- Stdout() //Explicit super() required tagged <- TaggedEntity("Server", "production") stdout.println(`${tagged.entityName()}: ${tagged.tag()}`) //Implicit super() (no-arg parent) simple <- SimpleDerived("extra") stdout.println(`${simple.baseLabel()}: ${simple.derivedLabel()}`)
Common mistakes
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
stdout.println(tagged.entityName().toUpperCase())
Correct:
stdout.println(`${tagged.entityName()}: ${tagged.tag()}`)
E05050 — The super() call must be the first statement. The parent must be fully initialized before the child assigns its own fields. See ek9 -h E05050 for details.
Incorrect:
TaggedEntity()
->
entityName as String
tag as String
this.tag: tag
super(entityName)
Correct:
TaggedEntity()
->
entityName as String
tag as String
super(entityName)
this.tag: tag
Other ways to ask this
- What is E05040 super without explicit parent?
- When must I call super() in a constructor?
- Does EK9 have implicit super() calls?
Coming from another language?
Java: implicit super() if parent has no-arg constructor. Python: must explicitly call super().__init__(). Kotlin: delegation in class header. C#: implicit base() if no-arg exists. EK9: implicit no-arg super(), explicit required when parent needs arguments, E05040 for super in a parentless class, E05080 for super(...) as a property initialiser.
Keywords: super, E05080, constructor, explicit, this, delegation, implicit, parent, missing, E05040