Generics ___________________________________________________________________________________________________ class C { Bird m() { return new Penguin() } } class D extends C { Animal m() { return new Bat() } } C c = new D() Bird x = c.m() Covariant return types => subclass return type must be a subtype of superclass return type class C { m(Bird x) { x.fly() } } class D extends C { m(Penguin x) { x.eatKrill() } } C c = new D() c.m( Penguin ) c.m( new Duck ) [ doesn't work!! ] class D extends C { m(Penguin x) { x.layEggs() } } c.m( new Duck ) [ works! ] contravariant arguments types -> can override with supertype arguments Side Note: Overloading is encoded as m$Bird m$Dinosour ___________________________________________________________________________________________________ T1' <: T1 T2 <: T2' ______________________ T1 -> T2 <: T1' -> T2' (a => b) === (!a v b) (a -> b) -> c + - - ___________________________________________________________________________________________________ class List { A get(int i) add(A) } List class List&String { String get(i) add(String) } Templates (in C++) are not generics. They solve the same problem tho. What the subtyping expansion between List <: List :> = != List ys = new List() List xs = ys does this work? List <: List xs.add(new Integer) ys.add(new Integer) ys.add(new Float) Integer i = xs.get(2) X (this will fail) Integer get(int) Number get(int) X add(Integer) add(Number) and now if we look at: List >: List i.e List <: List does this work? ys = xs ys.add(new Integer()) ys.add(new Float) X ys.get(1) So a a List cant be covariant and it cant be contravariant ... it can only be invariant (==) (does not change) Most people want this: List <: List So when your designing a language - you have to deside ... its a trade off between expressiveness vs safety vs simplicity expressiveness && safety ( <- this is java ) safty && simplicity ( <- C# ) C# ist and List are unrelated expressiveness && simplicity ( <- Dart ) Dart: homework Scala: ___________________________________________________________________________________________________ Java Wildcards List List List List List ( != List they are the almost the same but not ) A <: B List incomparable List List <: List covariant List :> List contravariant List <: List C <: A List <: List class List<> ext A> ? ext A get(i) add(? ext A) Ax xs.get(0) xs.add(new A) X - should not work ... ???? class List { E get() add(E) } List xs = new List() xs = new List() xs.add( new Integer() ) ___________________________________________________________________________________________________ class List { E x; E get() { return x; } void add(E x) { this.x = x; } } public class Main { void a() { List(); Number n = xs.get(); xs.add( new Integer(3) ); } void b() { List xs = new List(); Number n = xs.get(); xs.add( new Integer(3) ); } void c() { List xs = new List(); Number n = xs.get(); xs.add((Number) new Integer(3) ); class C { m(List xs) { xs.add(xs.get()); } } new C().m(xs); } } ___________________________________________________________________________________________________ Scala immutable class List [T] { def add(T) } X - cant do this mutable class ListBuffer[T] class Map[-K,+V] put(K,V) V get(K) List[Number] :> List[Integer] ___________________________________________________________________________________________________