Scala:试图理解Traits,'抽象覆盖'和堆叠

时间:2015-09-06 09:22:42

标签: scala traits

假设我有一个简单的抽象基类,如下所示:

abstract class MyAbstractBaseClass { 
    def hello : Unit 
}

然后我写了一个"堆叠"这样的特质:

trait MyTrait extends MyAbstractBaseClass { 
    abstract override def hello : Unit = 
    { 
        super.hello             
        println("How are you?"); 
    }
}

那么为什么Scala让我按如下方式定义一个子类:

class MyClass extends MyAbstractBaseClass with MyTrait {
    override def hello : Unit = println("Hello!")
}

error: overriding method hello in trait MyTrait of type => Unit;
 method hello needs `abstract override' modifiers

如果我尝试使用'抽象覆盖':

的建议
class MyClass extends MyAbstractBaseClass with MyTrait {
    abstract override def hello : Unit = println("Hello!")
}

error: `abstract override' modifier only allowed for members of traits

任何人都可以帮我理解这个吗?

P.S。我知道下面的确有效:

class MyClass extends MyAbstractBaseClass {
   override def hello : Unit = println("Hello!")
}

val x = new MyClass with MyTrait
x.hello

Hello!
How are you?

但我试图理解为什么前者没有。

总结:为什么我不能提供抽象基类的实现 - 同时还要利用特质的功能?

1 个答案:

答案 0 :(得分:2)

诀窍是你不能拥有"抽象"线性化流程中的方法,从super调用调用。

试试这个,你会看到它编译:

abstract class MyAbstractBaseClass {
  def hello : Unit
}

class SubClass extends MyAbstractBaseClass {
  def hello {
    println("toto")
  }
}


trait MyTrait extends MyAbstractBaseClass {
  abstract override def hello : Unit =
  {
    super.hello
    println("How are you?")
  }
}

class MyClass extends SubClass with MyTrait {  //note the CONCRETE SubClass here
  override def hello : Unit = println("Hello!")
}

new MyClass().hello

你得到了错误,因为编译器以MyTrait开头(在堆栈的顶部,所以第一个被调用),MyTrait通过super调用抽象方法......(MyAbstractBaseClass)=>它会崩溃,因为您的super电话无法立即定位具体方法。

在我的代码段中,您会注意到MyTrait位于顶部" (在线性化过程中)具体 Subclass类,这就是诀窍。