E11019: excessive inheritance depth - consider delegation with 'by'

Category: E11xxx Code quality and IR analysis · Reported in phase: PRE_IR_CHECKS · Classification: EXCESSIVE_INHERITANCE_DEPTH · All error codes

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

  1. Identify which ancestor provides the behavior you need
  2. Extract that behavior into a trait
  3. Use 'with trait of X by field' to delegate
  4. 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

  • E11019: inheritance depth (this error)
  • E05030: type not open to extension

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: