构成独立的特征

时间:2010-05-05 10:27:45

标签: scala traits

给出两个独立的特征:

trait T1 {
    def x = 42
}

trait T2 {
    def x = 0
}

如果我尝试在这两个特征中定义一个混合类,如:

class C extends T1 with T2

我收到编译错误:

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

现在假设T1和T2是独立开发的,因此没有覆盖,因为它们不会覆盖任何东西。那么如何定义C?像这样:

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

1 个答案:

答案 0 :(得分:10)

这被称为diamond problem。在Scala中有两种方法可以解决这个问题:

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
}

如果您现在致电new C().x,您将获得42,因为Scala会使用您最后混合的特性的实现。顺便说一下,new D().x会产生0。这意味着,为了解决钻石问题,您必须明确定义要使用的实现。

另一种方式如下:

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

new C().x的调用仍然会产生42,因为T2是混入的最后一个特征。不同之处在于您无需在x中定义C