How to mixin different type instances of same trait in Scala?

后端 未结 1 1286
鱼传尺愫
鱼传尺愫 2020-12-21 11:23

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         


        
相关标签:
1条回答
  • 2020-12-21 11:47

    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.

    0 讨论(0)
提交回复
热议问题