覆盖显式类型的自引用特征中的方法

时间:2013-11-24 16:12:05

标签: scala

我在使用Scala时遇到了一些麻烦,并明确键入了自引用特征。我有两个特点和一个实现:

trait A {
  def print(msg: String): Unit
}
class AImpl extends A {
  def print(msg: String): Unit = println(msg + " from A")
}
trait B { self: A =>
  override def print(msg: String): Unit = self.print(msg + " from B")
}
val a = new AImpl with B
a.print("Hello, World!")

我希望a.print("Hello, World!")打印Hello, World! from B from A。它编译时没有任何错误,但在运行时抛出了StackOverflowError。

这是我制作的Scastie

1 个答案:

答案 0 :(得分:2)

你所做的实际上是这样的:

trait B {
  def print(msg: String): Unit = this.print(msg + " from B") //Recursively build up stack until overflow
}

请注意,self只是this的别名,而不是super的别名。此外,由于A是自我类型,因此它不是B的超级类型,因此您无法调用super.print。因此,您已成功覆盖了print中的AImpl,但您没有调用您创建的print impl。

<强>更新

要实现您想要的目标,您需要扩展A而不是将其用作自我类型(对不起,但您无法通过自我类型执行您想要的操作):

  trait B extends A {
    abstract override def print(msg: String): Unit = super.print(msg + " from B")
  }