poly-morph =
 
ein Bezeichner (z. B. Unterprogramm-Name)
mit mehreren Bedeutungen
 
Arten der Polymorphie:
 
 
 
 
 
parametrische Polymorphie:
 
(oder der Compiler inferiert diese in einigen Fällen)
 
 
 
 
 
 
 
 
 
 
Anwendung: Sortieren mit Vergleichsfunktion
als Parameter
 
 
Wenn man einen generischen Typparameter
nur einmal braucht, dann kann er  
 
jedes Fragezeichen bezeichnet einen anderen (neuen) Typ:
 
 
Beispiel: Überladung im Argumenttyp:
static void p (int x, int    y) { ... }
static void p (int x, String y) { ... }
p (3, 4); p (3, "foo");
keine Überladung nur in Resultattyp, denn...
static int    f (boolean b) { ... }
static String f (boolean b) { ... }
class C {
   static T id<T> (T x) { return x; }
}
string foo = C.id<string> ("foo");
int    bar = C.id<int>    (42);
class Pair<A,B> {
  final A first; final B second;
  Pair(A a, B b) 
    { this.first = a; this.second = b; }
}
Pair<String,Integer> p = 
    new Pair<String,Integer>("foo", 42);
int x = p.second + 3;
vor allem für Container-Typen
(Liste, Menge, Keller, Schlange, Baum, ...)  
class C {
  static <A,B> Pair<B,A> swap (Pair<A,B> p) { 
    return new Pair<B,A>(p.second, p.first);
  } }
Pair<String,Integer> p = 
    new Pair<String,Integer>("foo", 42);
Pair<Integer,String> q = 
    C.<String,Integer>swap(p);
Typargumente können auch inferiert werden:
Pair<Integer,String> q = C.swap(p);
using System; class Bubble {
  static void Sort<T> 
    (Func<T,T,bool> Less, T [] a) { ...
      if (Less (a[j+1],a[j])) { ... } } 
  public static void Main (string [] argv) {
    int [] a = { 4,1,2,3 };
    Sort<int> ((int x, int y) => x <= y, a);
    foreach (var x in a) Console.Write (x);
} }
Ü: (allgemeinster) Typ und Implementierung 
einer Funktion
Flip, die den Vergleich umkehrt:
Sort<int> (Flip( (x,y)=> x <= y ), a) 
? heißen.
List<?> x = Arrays.asList
    (new String[] {"foo","bar"});
Collections.reverse(x);
System.out.println(x);
List<?> x = Arrays.asList
    (new String[] {"foo","bar"});
List<?> y = x;
y.add(x.get(0));