The very interesting feature of traits is possibility is dynamic mixin with other object. Why I’ve named it „dynamic”?. Because you can add trait not only to class but also to instance. It’s powerful feature that can change functionality of a class on the fly.
For example:
We have trait with complex mwthod. This trait is mixed into used class. Problem: In few cases we want to change the functionality of the implemented method.
What to do?
We have to make another trait that will be changed with default one.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
trait Debugger { def log(message: String): String } trait ADebugger extends Debugger { override def log(message: String) = { "A: "+message } } trait BDebugger extends Debugger { override def log(message: String) = { "B: "+message } } class Logger extends Debugger with ADebugger |
ADebugger
is default trait.
1 2 3 4 5 6 7 8 |
val l1 = new Logger val m = l.log("hello") //m: String = A: hello val l2 = new Logger with BDebugger //We mixin another trait into instance!! val m2 = l2.log("hello") //m: String = B: hello |
More to read:
http://www.artima.com/scalazine/articles/stackable_trait_pattern.html
.