What are the access modifier rules for method overrides?
← Override Mechanics · Ref: Q573
Note: override applies to both methods and operators (e.g., override operator ? as pure, override operator $ as pure).
When overriding a method, the access modifier must be at least as permissive as the parent. You cannot make an override more restrictive. The compiler reports E05130 for violations.
THE RULE
Public parent method requires public override (same level). Protected parent method allows protected or public override (same or wider). Private methods cannot be overridden (not visible to children).
THE ERROR: E05130
E05130 fires when an override is more restrictive than the parent. For example, making a public parent method protected or private in the child.
WHY THIS RULE
Liskov Substitution Principle: if code calls parent.method(), it expects child.method() to be equally accessible. Reducing access would break polymorphic code.
DEFAULT ACCESS
In EK9, methods without an explicit modifier are public. Use 'private' or 'protected' to restrict access.
NO PRIVATE OVERRIDE
Private methods are not inherited and cannot be overridden. They are invisible to child classes.
See Q570 for override basics. See Q572 for false override claims. See Q95 for field visibility.
Example
defines module qa.override.accessmodifiers defines constant MIN_ENHANCED_LENGTH <- 2 defines class Service as open //Public method (default) process() as pure -> request as String <- rtn as String: "processed: " + request //Protected method protected validate() as pure -> input as String <- rtn as Boolean: length input > 0 default operator ? //Correct: public override of public method EnhancedService extends Service override process() as pure -> request as String <- rtn as String: "enhanced: " + request //Correct: can widen protected to public //Or keep it protected (both are valid) override protected validate() as pure -> input as String <- rtn as Boolean: length input > MIN_ENHANCED_LENGTH default operator ? defines program AccessModifierRulesDemo() stdout <- Stdout() svc <- EnhancedService() stdout.println(svc.process("hello"))
Common mistakes
E07010 — Making an override more restrictive than the parent is forbidden. The parent process() is public, so a private override would violate the Liskov Substitution Principle. See ek9 -h E07010 for details.
Incorrect:
override private process() as pure
Correct:
override process() as pure
E07010 — Narrowing a protected parent method to private in the child violates access modifier rules. The override must be at least as permissive as the parent. See ek9 -h E07010 for details.
Incorrect:
override private validate() as pure
Correct:
override protected validate() as pure
Other ways to ask this
- What is E05130 method access modifiers differ?
- Can I change the visibility of an overridden method?
- Can I make an override more or less restrictive?
Coming from another language?
Java: same rule, cannot reduce visibility in override. Kotlin: same rule, override cannot be more restrictive. C#: same rule for virtual methods. EK9: E05130 enforces access modifier consistency in overrides.
Keywords: access, virtual, public, override, protected, modifier, restrictive, E05130, open, function, abstract, private, visibility, inherit