When is an explicit super() call required?
← Constructor Delegation · Ref: Q584
super() is only needed when the parent class requires constructor arguments. If the parent has a default (no-arg) constructor, EK9 implicitly calls it. E05040 fires if you call super() without an explicit parent class. E05080 fires if you use 'super' outside a class with an explicit parent.
WHEN SUPER() IS NEEDED
When the parent class only has constructors with parameters, the child must explicitly call super() with the right arguments. Without it, the parent cannot be initialized.
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.
E05080: SUPER WITHOUT PARENT
If you use 'super' (the keyword, not just the call) in a class that does not extend another, the compiler reports 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 must call super() because parent has no default constructor 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 E05080 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/E05080 for incorrect use.
Keywords: explicit, constructor, E05080, super, E05040, missing, parent, implicit, delegation, this