简体   繁体   English

如何重载超类方法

[英]How to overload super class method

I have an abstract class with a method that takes a List of Floats as a parameter: 我有一个抽象类,其方法将List of Floats作为参数:

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

I want to overload m in a concrete extending class: 我想在具体的扩展类中重载m:

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. 有一个override关键字,但在这种情况下,问题是编译时的TypeErasure。 The first method takes a List[Float] and the other one a List[Double] . 第一种方法采用List[Float] ,另一种采用List[Double]

These types will be erased, so you get two methods that take a List and return Unit . 这些类型将被删除,因此您将获得两个采用List和返回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 . 不是说你知道哪一个是正确的,用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)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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