2016-11-13 11 views
7

コード内のd.foo()は、CBDEの代わりにECBDに評価されます。Scalaのスタッカブル特徴

私は何が欠けていますか?

trait A { 
     def foo(): String = "" 
    } 

    trait B extends A { 
     abstract override def foo() = "B" + super.foo() 
    } 

    trait C extends B { 
     abstract override def foo() = "C" + super.foo() 
    } 

    trait D extends A { 
     abstract override def foo() = "D" + super.foo() 
    } 

    class E extends A{ 
     override def foo() = "E" 
    } 

    var d = new E with D with C with B; 
    d.foo() //prints CBDE 

私はそれが少し矛盾しているようだ、私は

class F extends A with D with C with B{ 
     override def foo() = "F" + super.foo() 
} 

以下のようなクラスFを持っており、

new F().foo 

をすれば、それは "FCBD" を印刷していること

に気づきましたクラスFは式と同じ方法で混合されますが、印刷順序が異なります。

答えて

4

new E with D with C with Bの最初のケースは完全にhereと説明されています。あなたは、その後、それ

  • 最初の呼び出し、
  • B#foo()
  • D#foo()
  • し、最終的にE#foo()呼び出すときに、その線形化はとても、EDBCです。

あなたがE形質を行い、最後にそれを混在させる場合:特色Eは線形で「最後」であるとちょうどfooをオーバーライドするためval d = new D with C with B with E、そしては、ちょうど"E"を返します。第一プリント"F"、 - - そのsuper.foo()"CBD"あるあなたが"F" + super.foo()としてfooを定義し、この場合superは、その線形ADBCあるA with D with C with Bのでnew F().foo() あるため

Fの場合は、異なっています。ところで

"A"を返すようにA#foo()を変更してみてください、そして、あなたはとても"A"が結果に表示されていない、とFにそれが"FCBDA"あるEにあなたがAさんfooを上書きしていることがわかります。