How do I override operators in EK9?
← Override Mechanics · Ref: Q577
Operators follow the same override rules as methods. When a parent class defines an operator, the child must use 'override operator' to replace it.
OVERRIDE OPERATOR ? (ISSET)
The most commonly overridden operator is '?'. Since all types inherit operator ? from the base, custom classes use 'override operator ?':
override operator ? as pure <- rtn as Boolean: name?
COMPARISON IS NOT OVERRIDDEN
Sameness ('<=>' or '==') is declared once per hierarchy and sealed: when a parent defines operator <=>, the child inherits it (and the generated '==', '<>', '<', '<=', '>', '>=') and may not redeclare '<=>', '==' or '#?' (E07182). A different ordering is a comparator function given to sort, not a second '<=>'.
OVERRIDE STRING
If a parent defines operator $, the child overrides it:
override operator $ as pure <- rtn as String: ...
DEFAULT OPERATOR
The 'default operator ?' shorthand can be used in any class. When a parent already has operator ?, using 'default operator ?' in the child effectively overrides it with the default implementation.
See Q570 for override basics. See Q245 for custom type operators. See Q568 for pure operators. See Q96 for class operators.
Example
defines module qa.override.operator defines class Measurement as open amount <- 0.0 Measurement() -> amount as Float this.amount: amount amount() as pure <- rtn as Float: amount operator <=> as pure -> other as Measurement <- rtn as Integer: amount <=> other.amount operator $ as pure <- rtn as String: $amount operator #? as pure <- rtn as Integer: #? amount override operator ? as pure <- rtn as Boolean: amount? //Child overrides operators Weight extends Measurement Weight() -> amount as Float super(amount) //Override string representation override operator $ as pure <- rtn as String: `${amount()} kg` default operator ? Length extends Measurement Length() -> amount as Float super(amount) override operator $ as pure <- rtn as String: `${amount()} m` default operator ? defines program OverrideOperatorDemo() stdout <- Stdout() weight <- Weight(75.5) stdout.println(`Weight: ${weight}`) lengthVal <- Length(1.82) stdout.println(`Length: ${lengthVal}`) //Comparison works through parent operator stdout.println(`Compare: ${weight <=> Weight(80.0)}`) stdout.println(`Equal: ${weight == Weight(75.5)}`)
Common mistakes
E05120 — When the parent class defines operator $, the child must use override operator $ to replace it. Omitting override on operator overrides triggers shadowing detection. See ek9 -h E05120 for details.
Incorrect:
operator $ as pure <- rtn as String: `${amount()} kg`
Correct:
override operator $ as pure <- rtn as String: `${amount()} kg`
E07500 — The parent operator $ is pure, so the child override must also be pure. Removing purity from the override violates the purity contract. See ek9 -h E07500 for details.
Incorrect:
override operator $ <- rtn as String: `${amount()} kg`
Correct:
override operator $ as pure <- rtn as String: `${amount()} kg`
Other ways to ask this
- How do I override operator ? in a child class?
- What is 'override operator' syntax?
- Must I use 'override' for operators too?
Coming from another language?
Java: no operator overloading. Kotlin: operator overloading exists, override keyword applies. C#: operator overloading but no inheritance override. EK9: operators follow identical override rules to methods, 'override operator' syntax.
Keywords: child, comparison, string, override, default, inherit, operator, abstract, virtual, isSet, open