Home > Back-end >  How do I accept a generic that extends a class in Scala
How do I accept a generic that extends a class in Scala

Time:12-24

I have something like the following...

class Base {
  def doSomething = {...}
}

class B extends Base{
  val text = "foo"
  ...
}
class C extends Base{
  val value = "bar"
}

I would like a method that accepts any class that extends Base but keeps its extended properties. I tried this...

def myMethod[A extends Base](obj: A): Unit{
  ...
}

But this didn't work. How do I create a method that allows this?

CodePudding user response:

The concept that you are looking for is that of an upper type bound. The standard notation for the subtyping relation is <:. This exact notation is also used in the Scala syntax for expressing type bounds:

// upper type bound, `A` must be subtype of `U`,
// analogous to Java's "A extends U"
def foo[A <: U]: Unit = ???

// lower type bound, `A` must be supertype of `L`,
// analogous to Java's "A super L"
def bar[A >: L]: Unit = ???

// Both upper and lower bounds simultaneously:
def baz[A >: U <: L]: Unit = ???

In your case, A should be subtype of Base, i.e. it should be bounded by Base from above: A <: Base

def myMethod[A <: Base](obj: A): Unit{
  ...
}

Another important difference to keep in mind when coming from Java is that in Scala, you have both the possibility for use-site variance, as well as declaration-site variance.

  • Related