What does 'override' mean in EK9 and when is it required?

← Override Mechanics · Ref: Q570

The 'override' keyword is required whenever a child class replaces a method from a parent class or trait. EK9 requires explicit override declarations to prevent accidental shadowing.

WHEN OVERRIDE IS REQUIRED

Whenever a method in a child class has the same name and signature as a method in a parent class or implemented trait, you must use 'override'. Omitting it produces E05110.

SYNTAX

Place 'override' before the method name:

  override process()
    -> text as String
    <- rtn as String: text.upperCase()

WHY EXPLICIT OVERRIDE

Prevents accidental shadowing: if you accidentally match a parent method, the compiler catches it. Documents intent: readers know this method replaces parent behavior. Catches renames: if the parent renames a method, the override declaration breaks, alerting you.

OVERRIDE WITH ABSTRACT

Implementing an abstract method also requires 'override':

  override calculate()
    <- rtn as Integer: 42

OVERRIDE WITH TRAITS

Implementing or replacing a trait method requires 'override':

  MyClass with trait of Printable
    override display()
      <- rtn as String: name

See Q571 for missing override keyword errors. See Q572 for false override claims. See Q573 for access modifier rules. See Q577 for operator override. See Q606 for method shadowing prevention.
See Q676 for override access hierarchy. See Q699 for return type covariance.

Example

defines module qa.override.basics

  defines class

    Vehicle as open
      speed() as pure
        <- rtn as String: "unknown speed"

      describe() as pure
        <- rtn as String: "a vehicle"

      default operator ?

    Car extends Vehicle as open
      //Override is required: same name and signature as parent
      override speed() as pure
        <- rtn as String: "fast"

      override describe() as pure
        <- rtn as String: "a car"

      default operator ?

    ElectricCar extends Car
      override speed() as pure
        <- rtn as String: "very fast"

      override describe() as pure
        <- rtn as String: "an electric car"

      default operator ?

  defines program

    OverrideBasicsDemo()
      stdout <- Stdout()

      vehicle <- Vehicle()
      stdout.println(`Vehicle: ${vehicle.describe()}, ${vehicle.speed()}`)

      car <- Car()
      stdout.println(`Car: ${car.describe()}, ${car.speed()}`)

      electric <- ElectricCar()
      stdout.println(`Electric: ${electric.describe()}, ${electric.speed()}`)

      //Polymorphic use
      vehicles <- List() of Vehicle
      vehicles += Vehicle()
      vehicles += Car()
      vehicles += ElectricCar()

      for item in vehicles
        stdout.println(`${item.describe()} goes ${item.speed()}`)

Common mistakes

E05120 — When a child class has a method matching a parent method, the override keyword is required. Omitting it causes method shadowing detection. See ek9 -h E05120 for details.

Incorrect:

speed() as pure

Correct:

override speed() as pure

E50001 — Renaming the variable means later references to 'vehicle' become unresolved, triggering E50001. See ek9 -h E50001 for details.

Incorrect:

vehicleXYZ <- Vehicle()

Correct:

vehicle <- Vehicle()
Other ways to ask this
  • How do I override a method in EK9?
  • When must I use the override keyword?
  • What is the override keyword in EK9?

Coming from another language?

Java: @Override annotation is optional but recommended. Python: no override concept. Rust: no method overriding (trait default implementations). Go: no inheritance. Kotlin: 'override' keyword is required (same as EK9). Swift: 'override' keyword required. C#: 'override' keyword required for virtual methods. EK9: 'override' keyword is mandatory, E05110 if missing.

Keywords: override, method, require, inherit, explicit, child, E05110, open, parent, virtual, abstract