エラー メッセージはわかりにくいかもしれませんが、動作は正しいと理解しています。
はinのようにfoo宣言されているため、混在する具象クラスには、(線形化順序に対して) beforeの具象 ( としてマークされていない) の実装が必要です。これは、線形化の順序で直前のトレイトを参照するためです。そのため、確実にbeforeの具体的な実装が必要であり、混同されていないと意味がありません。abstract overrideStackingTraitStackingTraitabstractfoo StackingTraitsuperfooStackingTraitsuper.foo
これを行う場合:
class Impl extends Base with StackingTrait {
def foo {}
}
線形化の順序はBase<- StackingTrait<-Implです。前の唯一の特性StackingTraitはBase、Baseの具体的な実装を定義していませんfoo。
しかし、これを行うと:
traitImplHelper extends Base {
def foo {}
}
class Impl extends ImplHelper with StackingTrait
線形化の順序は次のようになります: Base<- ImplHelper<- StackingTrait<-Impl
ここImplHelperには の具体的な定義が含まれており、foo間違いなくの前 StackingTraitです。
価値があるのは、(のように)ImplHelper後で混合した場合、同じ問題が再び発生し、コンパイルに失敗することです。StackingTraitclass Impl extends StackingTrait with ImplHelper
したがって、これは私にはかなり一貫しているように見えます。あなたが意図したようにコンパイルする方法を知りません。ただし、 orを簡単に記述できるようにすることよりも、簡単に記述できるようにする (別のクラス/特性を必要とせずにすぐにImpl定義できるようにする)ことに関心がある場合は、次のようにすることもできます。fooBaseStackingTrait
trait Base {
protected def fooImpl
def foo { fooImpl }
}
trait StackingTrait extends Base {
abstract override def foo { super.foo }
}
class Impl extends Base with StackingTrait {
protected def fooImpl {}
}
元のバージョンと同じように、各具象クラスを強制的にfoo( の形式でfooImpl) 実装すると、今度はコンパイルされます。ここでの欠点は、 while をfooImpl呼び出しsuper.fooてはならない (意味がなく、無限ループに入る) ことです。コンパイラはそれについて警告しません。