Can a class implement multiple traits in EK9?
← Classes and OOP · Ref: Q107
Yes, in EK9, a class can implement multiple traits. When traits have conflicting method signatures, you must resolve the ambiguity by providing an explicit override.
MULTIPLE TRAIT IMPLEMENTATION
List traits separated by commas:
Report with trait of Printable, Exportable
CONFLICT RESOLUTION
When two traits define the same method, override it in the class:
override format() <- rtn as String: Printable.format()
You can choose which trait's default to call using 'TraitName.method()' syntax.
ALLOW ONLY RESTRICTIONS
Traits can restrict which classes may implement them:
Response allow only JsonResponse, XmlResponse
Only the listed classes can use 'with trait of Response'.
AMBIGUOUS METHODS
The compiler detects when trait methods conflict and requires explicit resolution. This prevents silent bugs from accidental method shadowing.
See Q106 for trait basics. See Q108 for implementing traits step by step. See Q105 for dispatching with traits. See Q576 for class and trait override resolution.
Example
defines module qa.oop.multipletraits defines trait Serializable toText() <- rtn as String: "serialized" override operator ? as pure <- rtn as Boolean: true Loggable toText() <- rtn as String: "logged" logLevel() <- rtn as String: "INFO" override operator ? as pure <- rtn as Boolean: true defines class Event with trait of Serializable, Loggable message <- String() Event() -> message as String this.message: message override toText() <- rtn as String: message override operator ? as pure <- rtn as Boolean: message? defines program MultipleTraitsDemo() stdout <- Stdout() // === MULTIPLE TRAITS === event <- Event("User logged in") // toText() resolved by explicit override stdout.println(`Text: ${event.toText()}`) // logLevel() from Loggable (no conflict) stdout.println(`Level: ${event.logLevel()}`) stdout.println(`IsSet: ${event?}`)
Common mistakes
E05120 — When both Serializable and Loggable define toText(), the implementing class Event must explicitly override it to resolve the conflict. Omitting 'override' triggers E05120. See ek9 -h E05120 for details.
Incorrect:
toText()
Correct:
override toText()
E05120 — The '?' operator is defined in both traits. Event must use 'override operator ?' to resolve the conflict and provide its own implementation. See ek9 -h E05120 for details.
Incorrect:
operator ? as pure
Correct:
override operator ? as pure
E06150 — When two traits define the same method (toText() in both Serializable and Loggable), the implementing class must provide an explicit override to resolve the conflict. Without it, the compiler cannot determine which trait's default to use. See ek9 -h E06150 for details.
Incorrect:
//toText conflict not resolved
Correct:
override toText() <- rtn as String: message
Other ways to ask this
- How do I use multiple traits on one class in EK9?
- How does EK9 handle trait conflicts?
- What happens when two traits have the same method?
Coming from another language?
Java: class implements multiple interfaces, default method conflicts require override with InterfaceName.super.method(). Python: multiple inheritance with MRO (Method Resolution Order), diamond problem handled by C3 linearisation. Rust: multiple trait implementations, explicit disambiguation with <Type as Trait>::method(). Go: struct satisfies multiple interfaces implicitly, no conflict possible (no defaults). Kotlin: multiple interfaces, conflicts resolved with super<InterfaceName>.method(). EK9: multiple traits with 'with trait of A, B', conflicts resolved with 'TraitName.method()' syntax, 'allow only' restricts implementors.
Keywords: diamond, trait, override, conflict, open, virtual, multiple, implement, resolve, class, ambiguous, abstract, object-oriented, only, allow