Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Composing independent traits

Tags:

scala

traits

Given two independent traits:

trait T1 {
    def x = 42
}

trait T2 {
    def x = 0
}

If I try to define a class mixing in these two traits like:

class C extends T1 with T2

I get a compiler error:

error: overriding method x in trait T1 of type => Int;
method x in trait T2 of type => Int needs `override' modifier
class C extends T1 with T2
      ^
one error found

Now suppose T1 and T2 have been developed independently, hence no override as they do not override anything. How can C be defined then? Like this:

class C extends T1 with T2 {
    override def x = super.x
}

?

like image 925
45g Avatar asked May 05 '10 10:05

45g


1 Answers

This is known as the diamond problem. In Scala there are two ways to solve this:

trait T1 {
  def x = 0
}

trait T2 {
  def x = 42
}

class C extends T1 with T2 {
  override def x = super.x
}

class D extends T2 with T1 {
  override def x = super.x
}

If you call new C().x now, you will get 42 because Scala uses the implementation of the trait you mixed in last. new D().x will yield 0 by the way. This means, that in order to solve the diamond problem, you have to define explicitly which implementation you would like to use.

The other way is as follows:

trait T {
  def x: Int
}

trait T1 extends T {
  override def x = 0
}

trait T2 extends T {
  override def x = 42
}

class C extends T1 with T2

A call to new C().x will still yield 42 because T2 is the last trait mixed in. The difference is that you don't have to define x in C.

like image 103
Michel Krämer Avatar answered Oct 31 '22 16:10

Michel Krämer