在scala多重继承中,如何解决具有相同签名但返回类型不同的冲突方法?

Mar*_*cin 16 scala multiple-inheritance traits

请考虑以下代码:

trait A {
  def work = { "x" }
}

trait B {
  def work = { 1 }
}

class C extends A with B {
  override def work = super[A].work
}
Run Code Online (Sandbox Code Playgroud)

C不会在scala 2.10中编译,因为"在类型=> String的特征A中重写方法工作;方法工作具有不兼容的类型".

如何选择一种具体方法?

ser*_*jja 15

我担心没有办法做到这一点.该super[A].work方法仅适用于AB具有相同的返回类型.

考虑一下:

class D extends B

....

val test: List[B] = List(new C(), new D())
test.map(b => b.work) //oops - C returns a String, D returns an Int
Run Code Online (Sandbox Code Playgroud)


Jea*_*let 6

斯卡拉只是阻止你混合AB在一起,如果他们宣称具有相同的名称和不兼容签名的方法.


ghi*_*hik 6

你不能这样做.

看看这段代码:

val c = new C
val a: A = c
val b: B = c
Run Code Online (Sandbox Code Playgroud)

有没有办法,这两个这些线路可以工作:

val s: String = a.work
val i: Int = b.work
Run Code Online (Sandbox Code Playgroud)

如果我们允许这样的代码进行编译,则其中一个赋值必须以ClassCastException另一种方式抛出或失败.因此,根本不可能解决这种冲突.

我想你必须通过某种形式的授权解决这个问题,也许是这样的:

class C extends A {
  def toB = new B {
    //implement B methods by somehow delegating them to C instance
  }
}
Run Code Online (Sandbox Code Playgroud)


Max*_*xim 6

你不能在Scala中做到这一点.

解决这个问题的方法是将这些特征用作协作者

trait A {
  def work = { "x" }
}

trait B {
  def work = { 1 }
}

class C {
  val a = new A { }
  val b = new B { }

  a.work
  b.work
}
Run Code Online (Sandbox Code Playgroud)