Scala特征和抽象类型中的名称冲突

时间:2012-12-26 12:11:38

标签: scala traits abstract-type

我正在尝试定义特征C,该特征扩展了一些特征AB,......所有特征,CA,{ {1}},...实现共同特征B。特质T应该通过调用CTT中的A的实现来实现B

trait T{
  def f()
}
trait A extends T{
  def f(){
    print("A")
  }
}
trait B extends T{
  def f(){
    print("B")
  }
}

特质C的期望行为如下:

val x=new A with B with C[A,B]{}
x.f()
// should produce output
A
B

这里我试图定义特征C,它给出了编译错误:

trait C[A<:T,B<:T] extends T{
  self:A with B =>
  override def f(){
    // error: A does not name a parent class of trait C
    super[A].f()
    // error: B does not name a parent class of trait C
    super[B].f()
  }
}

我需要在C方法A.f()B.f()内进行通话。 这有什么解决方案吗?

1 个答案:

答案 0 :(得分:2)

如果要在特征内部提供实现,但也要确保子类实现定义,则可以使用abstract override组合告诉编译器:

trait T {
  def f()
}
trait A extends T {
  abstract override def f() {
    super.f()
    print("A")
  }
}
trait B extends T {
  abstract override def f() {
    super.f()
    print("B")
  }
}

trait C extends T {
  override def f() {
    // do your work here ...
  }
}

val x = new C with A with B
x.f()

要调用mixin层次结构中的下一个实现,您必须在super.f()方法调用中添加abstract override调用。因为这样的超级调用需要现有的实现,所以您需要创建的第一件事是C混合AB的实例。如果你在CA中混合B,编译器会抱怨,因为mixin-hierarchy从左到右执行,因此无法看到C的实现。