1

我有一个抽象类,其方法将浮点列表作为参数:

abstract class a {
    def m(p: List[Float]) {
        println("Passed List[Float] to p()")
    }
}

我想在一个具体的扩展类中重载 m :

class b extends a {
    def m(p: List[Double]) {
        println("Passed List[Double] to p()")
    }
}

有没有办法做到这一点?当我尝试它时,我收到此错误:

error: name clash between defined and inherited member:
method m:(p: List[Double])Unit and
method m:(p: List[Float])Unit in class a
have same type after erasure: (p: List)Unit
   def m(p: List[Double]) {
4

3 回答 3

2

有一个override关键字,但是在这种情况下,问题是编译时的 TypeErasure。第一种方法采用 a List[Float],另一种采用 a List[Double]

这些类型将被删除,因此您将获得两个采用 aList和 return的方法Unit。那就是冲突。

更改名称

现在简单的解决办法是给他们不同的名字。

使用泛型

abstract class a[T] {
    def m(p: List[T]) {
        println("Passed List[Float] to p()")
    }
}

class b extends a[Double] {
}
于 2013-05-17T20:37:16.193 回答
1

您必须以某种方式更改签名,因此您需要一个虚拟参数。

abstract class A {
  def m(p: List[Float]) { println(p.sum) }
}

class B extends A {
  def m(p: List[Double])(implicit dummy: Unit = ()) { println(p.product) }
}

现在

scala> val b = new B
b: B = B@6275a43c

scala> { b.m(List(3.0f,3.0f)); b.m(List(3.0, 3.0)) }
6.0
9.0

耶!

另一方面,这实际上会使事情变得不那么方便。

scala> val a = new A {}
a: A = $anon$1@1283bbd2

scala> a.m(List(3,3))
6.0

scala> b.m(List(3,3))
<console>:11: error: overloaded method value m with alternatives:
  (p: List[Double])(implicit dummy: Unit)Unit <and>
  (p: List[Float])Unit
 cannot be applied to (List[Int])
              b.m(List(3,3))
                ^

并不是说您无论如何都会知道哪一个是正确的,使用b. 因此,这确实可以保护您免受错误的影响,但代价是无法推断出正确的类型(因为正确的是模棱两可的)。

于 2013-05-17T23:24:03.603 回答
1

我不确定你到底想在这里做什么,但我有另一个建议给你

abstract class A {
  protected def _m(p: List[Float]) {
  }
}

class B extends A {
  def m(p: List[Double]){
    _m(p.map(_.toFloat))
  }
}

class C extends A {
  def m(p: List[Float]) {
    println("Passed List[Float] to p()")
    _m(p)
  }
}
于 2013-05-18T13:30:51.710 回答