Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I override a type parmeterized method with concrete type in scala?

I want to override a type-parameterized method by assigning a concrete type to the type-parameter, something like the code below.

trait A {
  def amethod[T](x: T): T
}
trait B extends A {
  def amethod(x: String): String = x ++ x
}

However the compiler gives amethod overrides nothing. I cannot put [String] after amethod in trait B, as syntactically it means a type parameter named String not the type java.lang.String. I am wondering whether and how I can do something like that.

Thanks a lot.

like image 207
Wen Li Avatar asked Mar 09 '23 23:03

Wen Li


2 Answers

amethod, as it's defined in trait A, is a generic method, meaning that each call can be applied to generic arguments.

What you are trying to say in trait B is to change the scope at which generality is expressed, moving it from the call site to the class definition itself. It's not possible to do it.

As it's been suggested in a comment, if you want to express generality in a class definition, the type parameter should be applied to the class, not to the method:

 trait A[T] {
   def amethod(x: T): T
 }

 trait B extends A[String] {
   override def amethod(x: String): String = x ++ x
 }
like image 161
stefanobaghino Avatar answered Mar 12 '23 11:03

stefanobaghino


As an explanation of the comment saying "B breaks its contract with A", consider this code:

def foo(): A = new B {} // legal because B extends A
def bar = foo().amethod[Int](0)

What should happen? If you are tempted to say that it should be rejected by looking at the body of foo, imagine it's an abstract method instead, and some class happens to implement it in this way.

like image 25
Alexey Romanov Avatar answered Mar 12 '23 12:03

Alexey Romanov