E11019: excessive inheritance depth - consider delegation with 'by'
What went wrong
Your class hierarchy is too deep. Depth of Inheritance Tree (DIT) counts levels from your class to the root. EK9 limits this to 4 levels.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 763 (What is the maximum inheritance depth allowed in EK9?)
Rationale
- DIT metric from Chidamber & Kemerer CK Metrics Suite (1994)
- EK9 limit: 4 levels
- Basili, Briand & Melo (IEEE TSE 1996): deeper classes were more likely to be fault-prone
- Deep hierarchies cause the "fragile base class problem"
- Changes to ancestors cascade unpredictably to descendants
- Explicitly shows what behavior is reused
- Allows swapping implementations at runtime
- Avoids fragile base class problem
- Keeps each class focused and testable
How to fix it
- Identify which ancestor provides the behavior you need
- Extract that behavior into a trait
- Use 'with trait of X by field' to delegate
- Your class stays shallow while keeping the functionality
Common causes
- Incrementally extended hierarchy without refactoring
- Using inheritance for code reuse instead of composition
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E11019: excessive inheritance depth - consider delegation with 'by'
#!ek9 defines module error.e11019.bad defines class Level1 as open value1 as Integer: 1 default operator ? Level2 extends Level1 as open value2 as Integer: 2 default operator ? Level3 extends Level2 as open value3 as Integer: 3 default operator ? Level4 extends Level3 as open value4 as Integer: 4 default operator ? Level5 extends Level4 as open value5 as Integer: 5 default operator ? //This class has depth 5 which exceeds maximum of 4 Level6 extends Level5 value6 as Integer: 6 default operator ?
Fixed: Keep the hierarchy shallow - delegate with by instead of extending again
#!ek9 defines module error.e11019.good defines trait Describes describe() as abstract <- rtn as String? defines class Level1 as open value1 as Integer: 1 default operator ? Level2 extends Level1 as open value2 as Integer: 2 default operator ? Level3 extends Level2 value3 as Integer: 3 default operator ? Description with trait of Describes override describe() <- rtn as String: "a level" Composed with trait of Describes by description description as Describes: Description() level as Level3: Level3() default operator ?
Questions and answers
These Q&A entries show E11019 and its fix: