How do I implement a trait for my class?
← Classes and OOP · Ref: Q108
Note: override applies to both methods and operators (e.g., override operator ? as pure, override operator $ as pure).
In EK9, implement a trait using 'with trait of' on the class declaration. You must override all abstract methods from the trait. You can optionally override default methods.
SYNTAX
Use 'with trait of TraitName' after the class name:
EmailSender with trait of Sender override send() -> message as String <- rtn as Boolean: true
IMPLEMENTING REQUIRED METHODS
Abstract trait methods must be overridden in the class:
defines trait Sender send() as abstract -> message as String <- rtn as Boolean?
The class must provide 'override send()' with a body.
OVERRIDING DEFAULT METHODS
Methods with bodies in the trait are optional to override:
defines trait Sender retry() <- rtn as Integer: 3
The class inherits retry() returning 3, or can override it.
TRAIT HIERARCHIES
Traits can extend other traits:
ReliableSender with trait of Sender acknowledge() as abstract <- rtn as Boolean?
A class implementing ReliableSender must implement both send() and acknowledge().
See Q106 for trait basics. See Q107 for multiple traits. See Q93 for class basics. See Q115 for dynamic classes implementing traits.
Example
defines module qa.oop.implementtrait defines trait Sender send() as abstract -> message as String <- rtn as Boolean? retry() as pure <- rtn as Integer: 3 ReliableSender with trait of Sender acknowledge() as abstract <- rtn as Boolean? defines class EmailSender with trait of Sender override send() -> message as String <- rtn as Boolean: true default operator ? SmtpSender with trait of ReliableSender override send() -> message as String <- rtn as Boolean: true override acknowledge() <- rtn as Boolean: true override retry() as pure <- rtn as Integer: 5 default operator ? defines program ImplementTraitDemo() stdout <- Stdout() // === BASIC TRAIT IMPLEMENTATION === email <- EmailSender() stdout.println(`Send: ${email.send("Hello")}`) stdout.println(`Default retry: ${email.retry()}`) // === TRAIT HIERARCHY === smtp <- SmtpSender() stdout.println(`Send: ${smtp.send("Hello")}`) stdout.println(`Acknowledge: ${smtp.acknowledge()}`) stdout.println(`Override retry: ${smtp.retry()}`)
Common mistakes
E05120 — When implementing an abstract trait method, the 'override' keyword is mandatory. EmailSender must use 'override send()' to implement Sender's abstract send method. See ek9 -h E05120 for details.
Incorrect:
send()
Correct:
override send()
E05120 — When overriding a default trait method, the 'override' keyword is required. SmtpSender overrides Sender's default retry() so it must use 'override'. See ek9 -h E05120 for details.
Incorrect:
retry() as pure
Correct:
override retry() as pure
E07130 — SmtpSender implements ReliableSender which extends Sender. The abstract send() from Sender must be overridden. Omitting it triggers E07130 — not declared abstract but still has abstract methods. See ek9 -h E07130 for details.
Incorrect:
//send not implemented override acknowledge()
Correct:
override send() -> message as String <- rtn as Boolean: true override acknowledge()
E05110 — The 'override' keyword claims a method exists in the hierarchy, but 'snd' does not match any method in Sender. This catches typos and refactoring errors — if a trait method is renamed, all implementors are flagged. See ek9 -h E05110 for details.
Incorrect:
override snd() -> message as String <- rtn as Boolean: true
Correct:
override send() -> message as String <- rtn as Boolean: true
Other ways to ask this
- What is the syntax for implementing a trait in EK9?
- How do I add trait methods to a class in EK9?
- How do I override trait default methods?
Coming from another language?
Java: 'class MyClass implements MyInterface', must implement all abstract methods, @Override annotation optional but recommended. Python: class MyClass(ABC) with @abstractmethod, no enforcement until instantiation. Rust: 'impl Trait for Type' block with all required methods. Go: implicit implementation, no keyword needed, just match method signatures. Kotlin: 'class MyClass : MyInterface', override keyword required. EK9: 'ClassName with trait of TraitName', override keyword required for all overridden methods, compiler enforces abstract method implementation.
Keywords: virtual, override, sender, class, trait, default, hierarchy, syntax, object-oriented, required, open, method, abstract, implement