这是对Scala如何提供多重继承而不引起Diamond问题的正确理解吗?

blu*_*sky 1 inheritance scala mixins

下面的代码:

trait t1 {
    def printt1 = println("In t1")
}

trait t2 {
    def printt1 = println("In t2")
}

class cclass extends t1 with t2
Run Code Online (Sandbox Code Playgroud)

导致此编译时错误:

class cclass inherits conflicting members: method printt1 in trait t1 of type => Unit and method printt1 in trait t2 
 of type => Unit (Note: this can be resolved by declaring an override in class cclass.)
Run Code Online (Sandbox Code Playgroud)

因此,这提供了编译时检查,该检查不允许多重继承,但允许混合,同时还可以防止Diamond问题:“多年来,多重继承一直是一个棘手的问题[需要引用],反对者指出它的复杂性和歧义性越来越高。 “钻石问题”之类的情况,如果一个以上的父类实现了某个特定功能,则该特定功能是从哪个父类继承的就可能是模棱两可的。” 来源:http : //en.wikipedia.org/wiki/Multiple_inheritance

为了解决上面的编译时错误,我只是重写t1:

class cclass extends t1 with t2 {

    override def printt1 = println("In cclass")

}
Run Code Online (Sandbox Code Playgroud)

这是Scala在Java和多重继承方面要克服的主要缺点(钻石问题)吗?

win*_*ner 5

不,您的代码中没有钻石问题。引用维基百科:

“钻石问题” ...是当两个类B和C从A继承而类D从B和C继承时产生的歧义。

这是一个演示Scala处理钻石问题的示例:

trait A {
  def x = 1
}

trait B extends A {
  override def x = 2
}

trait C extends A
class D extends B with C

(new D).x // == 2
Run Code Online (Sandbox Code Playgroud)

Scala从特征中“线性化”方法查找。对于D,它从D自身开始,然后从右边开始查看它继承的每个类或特征。这是深度优先的搜索,因此顺序为D -> C -> A -> B -> A,但是消除了重复项(表示钻石问题),从而将其保留在列表中,因此成为D -> C -> B -> A

但是,此代码:

trait A[A] {
  val x: A
}

trait B extends A[Int]
trait C extends A[String]
trait D extends B with C
Run Code Online (Sandbox Code Playgroud)

产生此错误:

trait D inherits different type instances of trait A:
  A[String] and A[Int]
Run Code Online (Sandbox Code Playgroud)

表明在某些情况下Scala仍然存在钻石问题。