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));