I\'m having a little problem understanding variance of methods when overloading.
While this perfectly works due to covariance in the return type
class Bl
You can override and change the return type to a subtype, but while accepting supertype for argument would satisfy the substitution principle, it is not allowed (this is just as in java) The reason is that you can also overload methods (several methods with same name, different arguments count and types) and your method will be considerered an overload. I guess this is mainly a question of JVM compatibility and of having a reasonable spec. Overloading already makes the scala spec rather complicated. Simply routing the overriden method to the overloaded one with the changed signature might be good enough:
class FooTest[A] extends Test[A] {
override def test(a: Fasel) : Fasel = test(a.asInstanceOf[Bla])
def test(a: Bla) : Fasel = new Fasel
}
What you can do is make a type parameter contravariant, provided in appears only in contravariant position (simplifying, appears as argument type and not as result type) but it is quite different:
trait Test[-A] {
// note the - before A.
// You might want to constraint with -A >: Fasel
def tester(a: A) : Bla = new Bla
}
class FooTest extends Test[Bla] {
override def tester(a: Bla): Fasel = new Fasel
}
val testOfBla: Test[Bla] = new FooTest
val testOfFasel: Test[Fasel] = testOfBla
// you can assign a Test[Bla] to a test[Fasel] because of the -A