* With Java Generics ```java static <X extends Comparable<? super X>> void sort(X[] xs) { ... } ``` * In Scala ```scala def sort[X <: Comparable[? >: X]] (Array[X] xs) = ... ``` * Use ```java class A implements Comparable<A>{} class B extends A {} B[] bs = ...; sort(bs); // B's are comparable as A's ```
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-book fa-stack-1x fa-inverse"></i></span> Variance Annotations ```scala trait Producer[+Y] { def apply () : Y } // Covariant trait Consumer[-X] { def apply (x:X) : Unit } // Contravariant trait Function[-X,+Y] { def apply (x:X) : Y } // Both trait Operator[X] { def apply (x:X) : X } // Invariant ``` ```scala trait Producer[-Y] { def apply () : Y } ^ error: contravariant type Y occurs in covariant position ``` ```scala trait Consumer[+X] { def apply (x:X) : Unit } ^ error: covariant type X occurs in contravariant position ``` ---
- Outside the scope of this course - Bounded polymorphism (Java, C#, Scala, Flow) - Java's use-site variance and wildcards - Adhoc polymorphism, typeclasses, implicit params - Check out Scala and Typescript