2015-10-15 61 views
2

我認爲以下2代碼快照將是等效的,但他們產生不同的結果。你能解釋爲什麼嗎?斯卡拉不同的行爲,當在特性混合飛行

1)性狀加入到類聲明:

trait M1 { 
    override def toString() = "m1" 
} 
trait M2 { 
override def toString() = "m2" 
} 
class C extends M1 with M2 { 
    override def toString() = { 
     s"C and ${super.toString()}" 
    } 
} 

val c = new C 
c.toString() //C and m2 

2)性狀在飛行中加入:

class C { 
    override def toString() = { 
     s"C and ${super.toString()}" 
    } 
} 

val c = new C with M1 with M2 
c.toString() //m2 

回答

3

兩種方法是不相同的。

版本一覆蓋toString應用mixin之後。

第二種方法混合使用C創建後,從而在M2中的toString將覆蓋C的一個

的樂趣

兩件事情都發生在這裏,首先在斯卡拉混入掃描從右到左。這就是M2在M1之前被調用的原因。第二個是M1和M2的新C將創建一個擴展C後面的合成類。這個合成類被增強以包含M2和M1,並且這個擴展將重寫C上的toString方法。在聲明C爲直接將M1和M2直接構建到C類中,並將C上的覆蓋方法踢入優先。