2017-02-23 156 views
2

我理解scala如何通過考慮所提到的特徵的順序來解決鑽石繼承的情況。我很想知道它是如何解決相同的問題的領域。這是我想了解的 -斯卡拉特質中的衝突域

class A {print("A")} 
trait B extends A {print("B") ; val x="b"} 
trait C extends B {print("C")} 
trait D extends A {print("D"); val x="d"} 

object TraitsEx extends App { 
    var d = new A with B with D 
    println(d.x) 
} 

上面的代碼不能編譯。

+0

不是錯誤消息說如何解決它? –

+1

您也可以在這裏粘貼編譯錯誤嗎? – WarFox

回答

2

好吧,不像你所看到的那樣神奇。如果這是A類的屬性,那麼你可以將其覆蓋 - 與類線性化,你已經知道,每個with X,其中X extends A會覆蓋值:

trait A { 
    val x = "a" 
} 

trait B extends A { 
    override val x = "b" 
} 

trait C extends A { 
    override val x = "c" 
} 

object Main { 
    def main(args: Array[String]): Unit = { 
    println((new A {}).x) 
    println((new A with B).x) 
    println((new A with B with C).x) 
    } 
} 

打印

a 
b 
c 

然而,當每個類都引入了它自己的x,編譯器無法證明覆蓋其他的x,那麼它將解決這個問題給你。這也表明一個解決辦法:

object TraitsEx extends App { 
    var d = new A with B with D { override val x = "d" } 
    println(d.x) 
} 

這樣你會覆蓋所有不同x S和去除歧義。

+0

請看看我的答案,請! – MotaF

2

Scala解決衝突的領域,通過解決它。

Error:(21, 16) <$anon: A$A123.this.A with A$A123.this.B with A$A123.this.D> inherits conflicting members: 
    value x in trait B of type String and 
    value x in trait D of type String 
(Note: this can be resolved by declaring an override in <$anon: A$A123.this.A with A$A123.this.B with A$A123.this.D>.) 
    var d = new A with B with D 
      ^

如果一個字段應該覆蓋另一個字段,則需要將其放入代碼中。如果沒有指定的覆蓋,編譯器將不會爲您做出任何決定。