What is method shadowing and how does EK9 handle it?
← Type Hierarchy Constraints · Ref: Q606
'Shadowing' usually means a child class declaring a method that silently replaces or hides a parent method. EK9 splits this into three cases and decides each one by the SIGNATURE (name plus parameter types):
1. SAME NAME, SAME SIGNATURE, NO 'override' - E05120
The child method would replace the parent's, but without saying so. EK9 rejects it with E05120: an accidental override is not allowed. Add 'override' if replacement is what you mean, or rename the method if it is not.
2. SAME NAME, SAME SIGNATURE, WITH 'override' - a proper override
Calls through a parent-typed reference reach the child's version: the object decides which method runs.
3. SAME NAME, DIFFERENT SIGNATURE - an overload, which is legal
A child may add format(text, prefix) beside the inherited format(text). Both are available on the child; a call picks the one whose parameters match. It is NOT an override, so marking it 'override' is E05110 (it does not override anything).
WHY THIS MATTERS
In Java, forgetting @Override means a typo in a parameter type silently creates a new method, and a matching signature without the annotation silently overrides. EK9 makes the intent explicit: an override must say 'override' (E05120 otherwise), and 'override' must really match a parent signature (E05110 otherwise).
WHAT TO DO
If replacing parent behaviour: use 'override' with the EXACT same parameter types. If adding behaviour: an overload with different parameters is fine, or use a distinct, descriptive name when the meaning differs.
See Q570 for override basics. See Q571 for missing override keyword. See Q572 for false override claims.
Example
defines module qa.typehierarchy.methodshadow defines class Formatter as open format() as pure -> text as String <- rtn as String: text describe() as pure <- rtn as String: "base formatter" default operator ? UpperFormatter extends Formatter //CORRECT: override with exact same signature override format() as pure -> text as String <- rtn as String: text.upperCase() override describe() as pure <- rtn as String: "upper formatter" //CORRECT: an overload - same name, different parameters, no 'override' format() as pure -> text as String prefix as String <- rtn as String: prefix + text.upperCase() //CORRECT: new method with a different name (no collision) formatWithPrefix() as pure -> text as String <- rtn as String: ">> " + text.upperCase() default operator ? defines function testProperOverride() base <- Formatter() upper <- UpperFormatter() require base.format("hello") == "hello" require upper.format("hello") == "HELLO" require upper.formatWithPrefix("hello") == ">> HELLO" require upper.format("hello", "# ") == "# HELLO" //Polymorphic: calling through parent type still dispatches correctly formatters <- List() of Formatter formatters += Formatter() formatters += UpperFormatter() for formatter in formatters result <- formatter.format("test") require result?
Common mistakes
E05120 — UpperFormatter.format has the same signature as Formatter.format, so it replaces it and must say so with 'override'. Without it, the compiler reports E05120. See ek9 -h E05120 for details.
Incorrect:
format() as pure
Correct:
override format() as pure
E05110 — Adding override to formatWithPrefix would be a false claim since Formatter has no method named formatWithPrefix. The compiler rejects override when no parent method matches. See ek9 -h E05110 for details.
Incorrect:
override formatWithPrefix() as pure
Correct:
formatWithPrefix() as pure
Other ways to ask this
- What is E05120 in EK9?
- How does EK9 detect method shadowing?
- Can a child class have a method with the same name but a different signature in EK9?
Coming from another language?
Java: a matching signature overrides with or without @Override; a different signature is an overload. C++: hiding is allowed by default, 'override' keyword optional. C#: 'new' keyword can explicitly shadow (EK9 has no such keyword). Python: no override concept, last definition wins. Kotlin: 'override' required, similar to EK9. Swift: 'override' required, similar to EK9. EK9: a same-signature method without 'override' is E05120; 'override' on a different signature is E05110; a different signature without 'override' is a legal overload.
Keywords: type, collision, overload, parent, circular, abstract, function, virtual, hierarchy, shadowing, child, inherit, E05120, signature, name, shadow, substitution, override, open