无法覆盖特征的抽象方法

时间:2018-04-25 05:47:07

标签: scala

我有一个未实现方法的特性(特征来自第三方库,所以我无法改变它)

scala> trait A {
     |  def B[T](b:T):T
     | }
defined trait A

我正在尝试扩展它并在其中实现方法B(尝试了三种方法)但是我收到以下错误。我的主要要求是,我希望将B T实施为Int(即B[Int]并返回b*2

scala> class C extends A {
     | def B(b:Int):Int = b*2
     | }
<console>:12: error: class C needs to be abstract, since method B in trait A of type [T](b: T)T is not defined
       class C extends A {
             ^

scala> class C extends A {
     | def B[T](b:T):T = b*2 //I know why this doesn't work but how could I implement B[Int]
     | }
<console>:13: error: value * is not a member of type parameter T
       def B[T](b:T):T = b*2
                          ^

scala> class C extends A {
     | override def B(b:Int):Int = b*2
     | }
<console>:12: error: class C needs to be abstract, since method B in trait A of type [T](b: T)T is not defined
       class C extends A {
             ^
<console>:13: error: method B overrides nothing.
Note: the super classes of class C contain the following, non final members named B:
def B[T](b: T): T
       override def B(b:Int):Int = b*2
                    ^

scala>

2 个答案:

答案 0 :(得分:2)

原始方法适用于任意输入类型T。如果要实现/覆盖它,还必须支持所有可能的输入类型。

如果你不能支持,那么最好不要继承这个特性。

如果你必须这样做,唯一的方法是这样做:

case class C() extends A {
  override def B[T](b: T): T = {
    val res = b.asInstanceOf[Int] * 2
    res.asInstanceOf[T]
  }
}

并祈祷只提供int值作为输入。

答案 1 :(得分:0)

为了创建一个扩展A的具体类,你需要为A中的所有抽象方法提供一个实现。所以在这种情况下,你需要为

提供一个实现。
def B[T](b: T):T

由于B是通用函数,因此您需要提供B的通用实现以及Int的专业化。

def B[T](b: T): T = b
def B(b: Int): Int = b*2

编译器将使用B的专用版本用于Int值,并使用通用版本用于所有其他值。

警告

之前的回答表明

override def B[Int](b: Int): Int = b

但在这种情况下,Int类型参数不是 Int数据类型,因此这是一个通用函数,与

完全相同
override def B[T](b: T): T = b

这提供了B identity函数的具体实现。这可能是也可能不是你想要的......