Why can't I change the access modifier when overriding a method?

← Classes and OOP · Ref: Q778

When you override a method, the child version must have the same access level as the parent. A protected method in the parent must remain protected in the child. Changing it would break the contract.

ACCESS RULES FOR OVERRIDE

- Public parent method: child must be public
- Protected parent method: child must be protected
- Private methods: cannot be overridden (not inherited)

WHY THIS RULE EXISTS

If Parent.process() is protected and Child makes it private, code in sibling classes that calls process() would fail. EK9 catches this at compile time.

THIS EXAMPLE

The Formatter class has a protected helper() method. The PrefixFormatter overrides it with the correct protected access.

See Q77 for inheritance. See Q84 for open classes. See Q90 for field visibility.

Example

defines module qa.classesandoop.overrideaccess

  defines class

    Formatter as open
      protected helper()
        -> text as String
        <- rtn as String: text

      format()
        -> message as String
        <- rtn as String: helper(message)

      default operator ?

    PrefixFormatter extends Formatter

      override protected helper()
        -> text as String
        <- rtn as String: `[PREFIX] ${text}`

      default operator ?

  defines program

    ShowFormatter()
      formatter <- PrefixFormatter()
      if formatter?
        stdout <- Stdout()
        stdout.println(formatter.format("hello"))

Common mistakes

E05130 — Changing the access from 'protected override' to 'private' narrows the visibility. The parent's helper() is protected, so the child must keep it protected. A private method with the same signature is treated as a different method, not an override — but EK9 detects this access mismatch. See ek9 -h E05130 for details.

Incorrect:

      private helper()

Correct:

      override protected helper()
Other ways to ask this
  • What triggers E05130 method access modifiers differ?
  • Can I make an overridden method private in EK9?
  • Why must override methods keep the same visibility?

Coming from another language?

Java: narrowing access on override is a compile error. Python: no access modifiers enforced. Rust: no method overriding. Kotlin: same as Java, cannot narrow access. Go: no method overriding. C#: override must match parent accessibility. EK9: same rule as Java/Kotlin/C#, compile-time enforcement.

Keywords: access, protected, visibility, private, method, override, modifier, contract, E05130