How to have multiple traits of same base trait implement the same method

自闭症网瘾萝莉.ら 提交于 2021-01-29 11:21:19

问题


I have a scenario with multiple traits inheriting from a fixed base trait. The base trait has an abstract method that each needs to implement. The class using these traits also needs to implement this method:

trait A {
    def f: Any
}

trait B1 extends A {
    val i: Int
    override def f: Any = println("B1: " + i)        
}

trait B2 extends A {
    val j: Int
    override def f: Any = println("B2: " + j)
}

class C extends A with B1 with B2 {
    val i = 1
    val j = 2

    override def f: Any = {
        super.f
        println("C::f")
    }
}

Then when I do a

new C().f

It only outputs "B1: 1" and not "B2: 2"

Is there a way I can define B1, B2 and C so that all implementations of f can be called?


回答1:


Well as you know which two diamond traits you mix in, you can call both super implementations and specify the trait from which you want to call each super implementation.

So, you could implement C like this:

class C extends A with B1 with B2 {
  val i = 1
  val j = 2

  override def f: Any = {
    super[B1].f
    super[B2].f
    println("C::f")
  }
}

And would get the output:

B1: 1
B2: 2
C::f



回答2:


This is an example of the diamond problem which Scala addresses by the process of linearisation:

Scala resolves method names using a right-first depth-first search of extended 'traits', before eliminating all but the last occurrence of each module in the resulting list. So, the resolution order is: [D, C, A, B, A], which reduces down to [D, C, B, A].

so the output should be in your case

B2: 2
C::f

so it seems it is not possible to call all the f overrides in both B1 and B2, instead only B2.f is resolved.



来源:https://stackoverflow.com/questions/57241306/how-to-have-multiple-traits-of-same-base-trait-implement-the-same-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!