I wanted to check different way how I can extend this code and then to mix this extensions of functionalities at the end as they are needed.
// Initial o
Let's simplify it:
trait Z {val a = 5}
trait K {val a = 6}
trait A[T] { def aa: T}
trait A1 extends A[Z] { def aa = new Z{}}
trait A2 extends A[K] { def aa = new K{}}
scala> class C extends A1 with A2
<console>:12: error: illegal inheritance;
class C inherits different type instances of trait A:
A[K] and A[Z]
So, what do you expect to be called, when you do (new C).aa
? If you actually don't care and just want to access those inside C
:
trait A {type T; protected def aa: T}
trait A1 extends A {type T >: Z; protected def aa = new Z{}}
trait A2 extends A {type T >: K; protected def aa = new K{}}
scala> class C extends A1 with A2 {
override type T = Any
override protected def aa = ???
def bbb:Z = super[A1].aa
def zzz:K = super[A2].aa
}
But I would recommend to choose some default method and inherit Z
from K
or K
from Z
to provide normal default implementation for C#aa
. Generally, the problem here is that traits in scala are intended for both mixins and polymorphism, so you can't just close their members for outside world (due to Liskov-Substitution), even if you don't actually need automatic cast to the supertype. See related question for details.