首页 文章

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

提问于
浏览
16

请考虑以下代码:

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

trait B {
  def work = { 1 }
}

class C extends A with B {
  override def work = super[A].work
}

由于"overriding method work in trait A of type => String; method work has incompatible type",类 C 将无法在scala 2.10中编译 .

如何选择一种具体方法?

4 回答

  • 15

    我担心没有办法做到这一点 . 仅当 AB 具有相同的返回类型时, super[A].work 方式才有效 .

    考虑一下:

    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
    
  • 6

    如果Scala声明具有相同名称和不兼容签名的方法,则Scala只会阻止您将 AB 混合在一起 .

  • 6

    你不能这样做 .

    看看这段代码:

    val c = new C
    val a: A = c
    val b: B = c
    

    这两条线都无法工作:

    val s: String = a.work
    val i: Int = b.work
    

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

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

    class C extends A {
      def toB = new B {
        //implement B methods by somehow delegating them to C instance
      }
    }
    
  • 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
    }
    

相关问题