在Scala中模拟多重继承

时间:2017-02-07 09:38:03

标签: scala inheritance multiple-inheritance

我正在开发一个基本上需要在正式意义上进行多重继承的项目:

class X
class Y

class XY extends X,Y

我有两个类,它们有一些定义并在整个代码中使用,即:

def alpha(x: X)
def beta(y: Y)

我想动态创建一个类XY,它只是合并来自XY的所有定义,但仍然保留了类型安全性。更具体地说,先前定义的alphabeta仍然接受此合并类。

我知道Scala允许混合特征,例如:

trait T
class A

val ta = new A with T

工作正常。

但是,我不能用课程来做:

class X
class Y

val xy = new X with Y

因为with ..必须是特质。

我试过通过以下方式来规避这个:

trait xV extends X
trait yV extends Y

val xy = new xV with yV

不幸的是,这不起作用并且出现以下错误:

Error:(33, 26) illegal inheritance; superclass X
 is not a subclass of the superclass Y
 of the mixin trait yV
    val xy = new xV with yV

任何帮助都将不胜感激。

修改

为了澄清,我无法修改类XY

2 个答案:

答案 0 :(得分:2)

Scala没有多重继承C ++样式,以避免可怕的Diamond Shape继承模式。

Scala提供的(仅)solution是以Trait s的形式提供mixins。要解决方法实现冲突,请选择最后一个Trait(最右边的Trait)。

因此,除非XY中至少有一个是特质,否则A将无法从两者继承(方法)

答案 1 :(得分:2)

字面意思这样做是不可能的。但

  

更具体地说,之前定义的alpha和beta仍然接受这个合并的类。

通过使用隐式转换可以实现此特定要求:

class XY {
  val x = new X
  val y = new Y
}

object XY {
  implicit def toX(xy: XY): X = xy.x
  implicit def toY(xy: XY): Y = xy.y
}

您还可以直接调用XY的方法。

但是,例如xy match { case x: X => ...不匹配,同样xy.isInstanceOf[X]也是假的。如果XY覆盖任何Object方法:equalshashCodetoString,则不会{ {1}}。