Delegate trait methods to another object using the 'by' keyword.

← Sealed Types and Traits · Ref: Q1129

Use 'by fieldName' to delegate all trait methods:

  DelegatingProcessor with trait of Processor by delegate
    delegate as Processor?

All trait methods are forwarded to the delegate field. Composition and delegation replace deep class hierarchies.

See Q1130 for chained delegation. See Q1131 for diamond resolution.

Example

defines module qa.sealedtraits.traitdelegationbasic

  defines trait

    Processor
      process() as pure
        <- result as String: "default"

  defines class

    SimpleProcessor with trait of Processor

      override process() as pure
        <- result as String: "simple"

      default operator ?

    DelegatingProcessor with trait of Processor by delegate
      delegate as Processor?

      default private DelegatingProcessor()

      DelegatingProcessor()
        -> proc as Processor
        require proc?
        delegate := proc

      default operator ?

  defines program

    TraitDelegationBasicDemo()
      stdout <- Stdout()

      simple <- SimpleProcessor()
      delegating <- DelegatingProcessor(simple)

      //Call goes through delegating -> delegate -> simple
      result <- delegating.process()
      stdout.println(`Result: ${result}`)

Common mistakes

E50020 — A trait is adopted with 'with trait of', not 'is' (which extends a class); using 'is' on a trait is an incompatible-genus error. See ek9 -h E50020 for details.

Incorrect:

    SimpleProcessor is Processor

Correct:

    SimpleProcessor with trait of Processor
Other ways to ask this
  • I need a class that forwards all trait method calls to a delegate field
  • In Kotlin I'd use 'by' delegation. Write the EK9 trait delegation equivalent
  • Given a Processor trait, create a delegating wrapper that forwards to a real processor
  • Implement the delegation pattern using 'with trait of X by field'

Coming from another language?

Kotlin: class Wrapper(p: Processor): Processor by p. Java: manual forwarding methods. Go: embedding. EK9: 'with trait of X by field' — compiler generates forwarding.

Keywords: proxy, composition, by, trait, forward, delegation