Reputation: 5459
I have an abstract class with a method that takes a List of Floats as a parameter:
abstract class a {
def m(p: List[Float]) {
println("Passed List[Float] to p()")
}
}
I want to overload m in a concrete extending class:
class b extends a {
def m(p: List[Double]) {
println("Passed List[Double] to p()")
}
}
Is there a way to accomplish this? When I try it I get this error:
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]) {
Upvotes: 2
Views: 835
Reputation: 8139
I'm not sure what exactly you are trying to do here but I have another suggestion for you
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)
}
}
Upvotes: 1
Reputation: 167891
You have to change the signature somehow, so you need a dummy argument.
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) }
}
and now
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
Yay!
On the other hand, this can actually make things less convenient.
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))
^
Not that you'd know which one was the right one anyway, with b
. So this does kind of protect you from errors, but at the cost of not inferring the correct type (since which is correct is ambiguous).
Upvotes: 2
Reputation: 28511
There is an override
keyword for that, however in this case the problem is TypeErasure at compile time. The first method takes a List[Float]
and the other one a List[Double]
.
These types will be erased, so you get two methods that take a List
and return Unit
. That is the clash.
Change the name
Now the simple resolution is to give them different names.
Use generics
abstract class a[T] {
def m(p: List[T]) {
println("Passed List[Float] to p()")
}
}
class b extends a[Double] {
}
Upvotes: 3