2010-05-05 31 views
8

給定兩個獨立的特質:撰寫獨立的特質

trait T1 { 
    def x = 42 
} 

trait T2 { 
    def x = 0 
} 

如果我嘗試定義這兩個特質:一類混合:

class C extends T1 with T2 

我得到一個編譯錯誤:

error: overriding method x in trait T1 of type => Int; 
method x in trait T2 of type => Int needs `override' modifier 
class C extends T1 with T2 
    ^
one error found 

現在假設T1和T2是獨立開發的,因此沒有覆蓋,因爲它們不覆蓋任何東西。那麼C如何定義呢?像這樣:

class C extends T1 with T2 { 
    override def x = super.x 
} 

回答

10

這就是所謂的diamond problem。在Scala中有兩種方法來解決這個問題:

trait T1 { 
    def x = 0 
} 

trait T2 { 
    def x = 42 
} 

class C extends T1 with T2 { 
    override def x = super.x 
} 

class D extends T2 with T1 { 
    override def x = super.x 
} 

如果你現在打電話new C().x,你會得到42因爲Scala使用您在過去的混合特徵的實現。順便說一下,new D().x將產生0。這意味着,爲了解決鑽石問題,你必須明確地定義你想要使用的實現。

另一種方法是如下:

trait T { 
    def x: Int 
} 

trait T1 extends T { 
    override def x = 0 
} 

trait T2 extends T { 
    override def x = 42 
} 

class C extends T1 with T2 

new C().x調用仍然會產生42因爲T2是最後的性狀的混合不同的是,你不必在C定義x

+0

這很有趣。如果'T1'和'T2'中'x'的兩個定義有不同的類型,這似乎是一個不可避免的問題。 如果類型不匹配,Scala中是否有一種巧妙的方法來修復這些名稱衝突? – Mike 2010-05-05 23:06:30

+0

使用我的第一個例子,然後定義'C'如下:'class C用T2 {override def x = super [T1] .x}'擴展T1。當然,你也可以調用'super [T2] .x'。 – 2010-05-06 04:04:26