Based on the Java background, I understand that this does not compile.
public static class SuperClass {} public static class SubClass extends SuperClass {} public static <T, U extends T> U returnSub(T sup, U sub) { return sub; } public static void main(String[] args) { SuperClass parent = new SuperClass(); SubClass child = new SubClass(); returnSub(parent, child); returnSub(child, parent);
The last line causes a compiler error (EDIT: at least on jdk1.6.0_65):
Associated mismatch: the general returnSub (T, U) method of type Test is not applicable for arguments (Test.SubClass, Test.SuperClass). The deduced type Test.SuperClass is not a valid replacement for a limited parameter
So, I was surprised that this works in Scala. I wrote an example code below (which, as far as I can tell, expresses the same “logic”):
class SuperClass class SubClass extends SuperClass def returnSub[Type, SubType <: Type](supArg: Type, subArg: SubType): SubType = { subArg } override def main(args: Array[String]): Unit = { val parent = new SuperClass() val child = new SubClass() val iAmOkWithThat: SubClass = returnSub(parent, child) val iDontGetThat: SuperClass = returnSub(child, parent) }
I think the Scala compiler is smart enough to say "OK, child is an instance of SubClass , but I can't call returnSub if I say so, so let me try if I think of child as an instance of SuperClass , and, well, it works, so let's do it. "
Is that what happens (and if so, can you point out this language specification)? Or maybe my Scala transform is not equivalent to my Java code?
Thanks!