2017-02-23 122 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 
      ^

如果一个字段应该覆盖另一个字段,则需要将其放入代码中。如果没有指定的覆盖,编译器将不会为您做出任何决定。