1

Float のリストをパラメーターとして受け取るメソッドを持つ抽象クラスがあります。

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 です。最初のメソッドは aList[Float]を取り、もう 1 つのメソッドは a を取りますList[Double]

Listこれらの型は消去されるため、 aと returnを受け取る 2 つのメソッドが得られます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 {
  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 に答える
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 に答える