简体   繁体   中英

How to overload super class method

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]) {

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] {
}

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).

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)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM