Considering:
abstract class Base {
def something() = println("Base")
}
trait TraitA extends Base {
abstract override def something() = { super.something(); println("TraitA"); }
}
class Child extends Base {
override def something() {
println("Child")
}
}
And then:
val x = new Child with TraitA
x.something()
I get:
Child
TraitA
But if I use:
class Child extends Base with TraitA {
override def something() {
println("Child")
}
}
val x = new Child
x.something()
I'd get only:
Child
So what are the differentes of using a trait at construction site or declaration site? Can I have the first behavior (stackable traits) while extending/with'ing the trait in the declaration of the class?
Stackable traits in Scala refers to being able to mix in multiple traits that work together to apply multiple modifications to a method. This involves invoking super.theMethod and modifying its input and/or output. But what is super in the context of a trait? The class (or trait) the trait extends from? The class the trait is being mixed into? It depends! All the mixed in traits and all the superclasses are linearized. super invokes the nearest preceding definition further up the chain.
read full post
In your case:
1. super.something() == Child.something()
2. super.something() == Base.something() and Child.something() overrides whole chain
Type of mixin doesn't matter:
class Child2 extends Child with TraitA
val x2 = new Child2
x2.something()
/*
Child
TraitA
*/
class Child3 extends Base with TraitA
val x3 = new Child3
x3.something()
/*
Base
TraitA
*/
In the first example, you override the method of Base
first and then you mix TraitA
which will stack.
In the second example, first you mix TraitA
and then you override the resulting (stacked) method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With