Search code examples
scalatraitsdiamond-problem

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


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?


Solution

  • 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