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
#!ek9 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: E05120, abstract, child, circular, collision, function, hierarchy, inherit, name, open, overload, override, parent, shadow, shadowing, signature, substitution, type, virtual