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.