给出两个独立的特征:
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
}
答案 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