What is the maximum class inheritance depth in EK9?
← Code Quality · Ref: Q729
EK9 limits inheritance depth to prevent fragile base class problems. The limits vary by construct type:
- Class: DIT 4 (max 5 classes in a chain)
- Record: DIT 2
- Trait: DIT 4
- Component: DIT 4
- Function: DIT 3
DIT (Depth of Inheritance Tree) counts ancestor levels. A base class has DIT=0, its child DIT=1, and so on.
WHY LIMIT INHERITANCE DEPTH
This is a DESIGN limit, not a technical one. Deep hierarchies cause:
1. Fragile base class problem: changes at the top cascade unpredictably through all descendants
2. Comprehension burden: understanding a class at DIT=6 requires reading 7 class definitions
3. Constructor complexity: super() chains grow error-prone with each level
4. Testing explosion: each level multiplies the number of state combinations to test
EK9 OFFERS BETTER ALTERNATIVES
Instead of deep inheritance, EK9 provides:
- Traits for shared behavior without hierarchy depth
- Composition (has-a) instead of inheritance (is-a)
- The 'by' delegation keyword for forwarding calls
THIS EXAMPLE
The hierarchy below has DIT=4 for the leaf class (exactly at the class limit). Adding one more intermediate level would trigger E11019.
See Q697 for inheritance depth overview. See Q611 for hierarchy validation. See Q602 for circular hierarchy detection.
Example
defines module qa.codequality.inheritanceboundary defines trait <?- Traits add behavior without increasing inheritance depth. -?> Describable describe() as pure <- rtn as String: "describable" defines class //DIT=0: abstract root Vehicle as abstract engineType() as pure abstract <- rtn as String? default operator ? //DIT=1: first concrete level TwoWheeler extends Vehicle as open wheelCount <- 2 override engineType() as pure <- rtn as String: "two-wheeler" getWheelCount() as pure <- rtn as Integer: wheelCount default operator ? //DIT=2: specialization Motorcycle extends TwoWheeler as open displacement <- Integer() Motorcycle() -> displacement as Integer this.displacement: displacement getDisplacement() as pure <- rtn as Integer: displacement override engineType() as pure <- rtn as String: "motorcycle" default operator ? //DIT=3: further specialization SportsBike extends Motorcycle as open hasFairing <- Boolean() SportsBike() -> displacement as Integer hasFairing as Boolean super(displacement) this.hasFairing: hasFairing override engineType() as pure <- rtn as String: "sports" default operator ? //DIT=4: exactly at the class limit //Adding one more level here would trigger E11019 RacingBike extends SportsBike raceCategory <- String() RacingBike() -> displacement as Integer raceCategory as String super(displacement: displacement, hasFairing: true) this.raceCategory: raceCategory getRaceCategory() as pure <- rtn as String: raceCategory override engineType() as pure <- rtn as String: `racing (${raceCategory})` default operator ? defines program InheritanceDepthBoundaryDemo() stdout <- Stdout() racer <- RacingBike(displacement: 600, raceCategory: "Supersport") stdout.println(racer.engineType()) stdout.println(racer.getRaceCategory()) stdout.println($racer.getDisplacement()) stdout.println($racer.getWheelCount())
Common mistakes
E50060 — Adding another level to the inheritance chain pushes DIT from 4 to 5, exceeding the class limit of 4. Use traits or composition instead of deeper inheritance. See ek9 -h E50060 for details.
Incorrect:
TrackBike extends SportsBike as open default operator ? RacingBike extends TrackBike
Correct:
RacingBike extends SportsBike
Other ways to ask this
- What triggers E11019 excessive inheritance depth?
- How deep can class hierarchies be?
- What is the DIT limit for classes?
- What are the DIT thresholds for each EK9 construct type?
Coming from another language?
Java: no depth limit (only convention). Python: MRO handles deep chains but they are a smell. C++: no depth limit. Kotlin: no depth limit. Rust: no inheritance. Go: no inheritance (uses embedding). EK9: compile-time depth limit with different thresholds per construct type.
Keywords: quality, class, trait, limit, boundary, hierarchy, depth, clean-code, fragile, DIT, inheritance, base, E11019, composition