trait TSM
{
def fit[T <: TSM](): FR[T]
}
This defines a trait with a method fit
that for any type T
returns an instance of FR[T]
class SMA extends TSM
{
override def fit[SMA]() =
{
val fim = new SMAM(new SMAO("x"))
new FR[SMA](fim)
}
}
This overrides method fit
defined in the trait. SMA
in method definition is a type parameter, not a reference to the class name. You can (probably, should) replace it with T
, it'll be equivalent, but a bit less confusing:
override def fit[T <: TSM](): FR[T] = new FR(new SMAM(new SMAO("x")))
This will give you a more descriptive error - something to the effect that you are trying to return FR[SMA]
where FR[T]
is expected.
The bottom line is you cannot make a method in subclass less "generic" than it is declared in a superclass. To better understand why that is the case, consider this:
abstract class Foo extends TSM
val sma: TSM = new SMA()
val foo: FR[Foo] = sma.fit[Foo]()
This should work: sma
is an instance of TSM
, and TSM.fit
is supposed to work for any type parameter which is a subclass of TSM
, which Foo
clearly is.
But your SMA.fit
as written can only return FR[SMA]
, so the snippet above would not work if it was allowed.
How to fix this?
Well, that depends on what you actually want. One possibility is to parametrize the trait itself rather than the method:
trait TSM[T <: TSM[_]] {
def fit(): FR[T]
}
class SMA extends TSM[SMA]
{
override def fit() = new FR(new SMAM(new SMAO("x")))
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…