假设我有一个简单的抽象基类,如下所示:
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?
但我试图理解为什么前者没有。
总结:为什么我不能提供抽象基类的实现 - 同时还要利用特质的功能?
答案 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
类,这就是诀窍。