这是否正确理解Scala如何提供多重继承而不会导致Diamond问题

时间:2014-06-10 22:50:37

标签: scala inheritance mixins

代码如下:

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

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

class cclass extends t1 with t2

导致此编译时错误:

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.)

因此,这提供了编译时检查,它不允许多重继承,但允许mixin同时也防止Diamond问题:“多重继承多年来一直是一个棘手的问题[引证需要],反对者指出其复杂性增加在诸如“钻石问题”之类的情况下,如果多个父类实现了所述特征,那么从哪个父类继承特定特征可能会模糊不清。来源:http://en.wikipedia.org/wiki/Multiple_inheritance

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

class cclass extends t1 with t2 {

    override def printt1 = println("In cclass")

}

这是主要的缺点(Diamond问题)Scala是否克服了Java和多重继承?

1 个答案:

答案 0 :(得分:4)

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

  

"钻石问题" ......当两个人产生歧义时   B和C类继承自A,D类继承自B和   下进行。

这是一个演示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

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

是否会产生此错误:

 trait D inherits different type instances of trait A:
A[String] and A[Int]

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