Reputation: 13
I'm trying define a trait C
which extends some traits A
,B
,... All traits,C
and A
,B
,... implement a common trait T
. Trait C
is supposed to implement T
by calling the implementations of T
in A
,B
,..:
trait T{
def f()
}
trait A extends T{
def f(){
print("A")
}
}
trait B extends T{
def f(){
print("B")
}
}
The desired behavior of trait C
is as follows:
val x=new A with B with C[A,B]{}
x.f()
// should produce output
A
B
Here my attempt to define trait C, which gave compilation errors:
trait C[A<:T,B<:T] extends T{
self:A with B =>
override def f(){
// error: A does not name a parent class of trait C
super[A].f()
// error: B does not name a parent class of trait C
super[B].f()
}
}
I need to call within C
methods A.f()
and B.f()
.
Is there any solution to this?
Upvotes: 1
Views: 729
Reputation: 53358
If you want to provide an implementation inside of a trait but also ensure that subclasses implement the definition, it is possible to tell this the compiler with the abstract override
combination:
trait T {
def f()
}
trait A extends T {
abstract override def f() {
super.f()
print("A")
}
}
trait B extends T {
abstract override def f() {
super.f()
print("B")
}
}
trait C extends T {
override def f() {
// do your work here ...
}
}
val x = new C with A with B
x.f()
To call the next implementation in the mixin-hierarchy you must add a super.f()
call inside of the abstract override
method call. Because such a super call requires an existing implementation the first thing you need to create is an instance of C
that mixins A
and B
. If you mixin C
in A
or B
the compiler will complain because the mixin-hierarchy is executed from left to right, thus the implementation of C
can not be seen.
Upvotes: 2