E05110: does not 'override' any method/operator

Category: E05xxx Explicit type symbol definition · Reported in phase: FULL_RESOLUTION · Classification: DOES_NOT_OVERRIDE · All error codes

What went wrong

You declared 'override' on a method or operator, but no parent class or trait provides a method/operator with that name and signature - there is nothing to override. (A private parent method does not count: it is not inherited, so it cannot be overridden either.)

An override has EXACTLY the parent's signature: the same name and exactly the same parameter types, in order (a covariant return is allowed). A method of the same name taking OTHER types - narrower, wider or a different number - is a new overload, not an override: 'override process() -> t as Triangle' beside a parent 'process() -> s as Shape' is this error. A call through a parent-typed reference would never reach it.

Operators on a plain class, record or component: every aggregate inherits 'operator ?' from the root type, so its '?' MUST be 'override' (E05120 if you omit it) - but the other operators ('$', '+', '<=>', '==', '#?' on an aggregate with no parent that defines them) have NO parent version, so 'override operator $' is this error. For the override check the root contributes ONLY '?'. If you wrote both, expect E05120 on '?' when you remove 'override' from BOTH: only take it off the one the compiler names.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 572 (What happens if I claim 'override' but no parent method m...)
  • ek9 -q 576 (How do overrides work when a class implements a trait and...)
  • ek9 -q 108 (How do I implement a trait for my class?)
  • ek9 -q 579 (How do overrides work in a three-level trait hierarchy?)

How to fix it

  1. Read WHICH member the error names, and fix only that one.
  2. If it is a NEW method/operator with no parent version - including one that takes other parameter types than the parent's (an overload) - remove 'override'. To handle sub-types of the parent's parameter, make the parent's method 'as dispatcher' and add handlers.
  3. If you meant to override: make the name, parameter types and purity match the parent's exactly (use ek9_query_effective_api / 'ek9 -h <Type>' to see what the parent actually declares), and check the parent member is not private.
  4. Do not "fix" this by removing 'override' everywhere - the members that DO override a parent (the '?' of every aggregate) then fail with E05120.

Rationale

'override' is a claim the compiler verifies: "there is a parent member and I am replacing it". Accepting the keyword when no such member exists would hide a typo or a renamed parent method as silently-new behaviour. The pair with E05120 makes overriding explicit in both directions.

Common causes

  • 'override operator $' (or '<=>', '==', '#?') on a class, record or component with no parent - for the override check the root contributes only '?'
  • Typo in the method name, or a parent method that was renamed/removed
  • Parameter types that differ from the parent's - even a sub-type of the parent's parameter type is a different signature (an overload)
  • The parent member is private
  • Fixing E05120 by adding 'override' to EVERY operator instead of the one named

See also

  • E05110: 'override' with no matching parent member (this error)
  • E05120: parent member matches but 'override' is MISSING (the mirror case)
  • E05100: 'override' on a program/service method, which can never be extended

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E05110: does not 'override' any method/operator

#!ek9
defines module error.e05110.bad

  defines class

    C1 as open
      //The method sub-classes give their own version of
      private someMethod()
        -> text as String
        <- rtn as String: text

    //Brackets the text
    C3u extends C1
      override someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

    //Brackets the text, for sub-classes only
    C4u extends C1
      override protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Fixed: Let sub-classes see it: protected, not private, and overridden at the same access

#!ek9
defines module error.e05110.good.fix

  defines class

    C1 as open
      //The method sub-classes give their own version of
      protected someMethod()
        -> text as String
        <- rtn as String: text

    //Brackets the text
    C3u extends C1
      override protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

    //Brackets the text, for sub-classes only
    C4u extends C1
      override protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Fixed: A private method is not inherited: a sub-type method of the same name is a new method, without override

#!ek9
defines module error.e05110.good

  defines class

    C1 as open
      private someMethod()
        -> text as String
        <- rtn as String: text

    //A NEW method: the private one in C1 is not inherited
    C3 extends C1
      someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Fixed: To override it, make the parent method protected (or public) and keep that access

#!ek9
defines module error.e05110.good.overridable

  defines class

    C5 as open
      //Protected or public - can be overridden
      protected someMethod()
        -> text as String
        <- rtn as String: text

    //Now it IS an override
    OkOverrides1 extends C5
      override protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Questions and answers

These Q&A entries show E05110 and its fix: