简体   繁体   中英

Unable to override an abstract method of a trait

I have a trait with an unimplemented method (the trait is from a 3rd party library so I can't change it)

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

I am trying to extend it and implement the method B in it (have tried three ways) but I am getting the following error. My main requirement is that I want to implement B for T as Int (ie B[Int] and return 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>

Original method is supposed to work for arbitrary input type T . If you want to implement/override it you also have to support it for all possible input types.

So it's better not to inherit from this trait if you can't support it.

If you do have to do it the only way is do like that:

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

and pray that only int values will be supplied as an input.

In order to create a concrete class that extends A you need to provide an implementation for all abstract methods in A. So in this case, you need to provide an implementation for

def B[T](b: T):T

Since B is a generic function you need to provide a generic implementation of B as well as your specialisation for Int .

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

The compiler will use the specialised version of B for Int values and the generic version for all other values.

Warning

A previous answer suggests

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

But in this case the Int is a type parameter and not the Int data type, so this is a generic function and is exactly the same as

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

This provides a concrete implementation of B that is the identity function. This may or may not be what you want...

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