E05130: methods with same signature have different access modifiers

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

What went wrong

When overriding a method, its access modifier must be the SAME as the parent's - it cannot become less accessible (public to protected) or more accessible (protected to public). It must match EVERY parent that declares the method - the super class and each trait - so a protected super method and a public trait method of the same signature cannot both be overridden by one method.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 778 (Why can't I change the access modifier when overriding a ...)

Access level rules

  • Public parent -> child must be public (same)
  • Protected parent -> child can be protected OR public (same or wider)
  • Private methods -> cannot be overridden (not inherited)

How to fix it

  1. Use same access level as parent method
  2. Or use MORE permissive access (protected -> public is OK)
  3. Never use more restrictive access

Rationale

If code can call parent.process(), it expects child.process() to also be callable. Reducing access would break the Liskov Substitution Principle: anywhere you use Parent, you should be able to use Child.

Common causes

  • Adding 'private' to hide implementation detail (wrong approach)
  • Wanting different access than parent designed for
  • Copy-paste with wrong access modifier

See also

  • E05130: override reduces access (this error)
  • E06180: accessing method you don't have permission for (different context)

Examples

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

Fails with E05130: methods with same signature have different access modifiers

#!ek9
defines module error.e05130.bad

  defines class

    C5 as open
      //Protected method
      protected someMethod()
        -> text as String
        <- rtn as String: text

    //ERROR: Cannot restrict protected to private
    C6 extends C5
      private someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

    //ERROR: Cannot expand protected to public
    C7 extends C5
      someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

    C8 as open
      //Public method (no modifier = public)
      someMethod()
        -> text as String
        <- rtn as String: text

    //ERROR: Cannot restrict public to private
    C9 extends C8
      private someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

    //ERROR: Cannot restrict public to protected
    C10 extends C8 as open
      protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Fixed: An override keeps the access modifier of the method it overrides

#!ek9
defines module error.e05130.good

  defines class

    C5 as open
      protected someMethod()
        -> text as String
        <- rtn as String: text

    //Keep the same access modifier (protected)
    OkOverrides1 extends C5
      override protected someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

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

    //Keep the same access modifier (public)
    OkOverrides2 extends C8
      override someMethod()
        -> text as String
        <- rtn as String: `[ ${text} ]`

Questions and answers

These Q&A entries show E05130 and its fix: