Generische Programmierung
Generische Programmierung ist ein Konzept in verschiedenen Programmiersprachen, um Funktionen und Algorithmen möglichst universell einsetzbar und unabhängig von den verwendeten Datentypen umzusetzen.
Zum Beispiel ist es für eine Liste vollkommen irrelevant, welche Art von Daten sie enthält. Es ist also nicht sinnvoll, vorzuschreiben, welchen Typ die Daten in einer Liste haben sollen. Um sicherzugehen, dass die Daten in dieser Liste aber alle gleich verarbeitet werden können, ist es wünschenswert, vorzuschreiben, dass sie alle denselben Typ haben sollen.
In Java kann man dies mit generischen Typen umsetzen. Diese werden bei der Verwendung einer generischen Klasse als so genannter Typparameter angegeben und in spitzen Klammern geschrieben.
Ein Beispiel:
ArrayList<String> messages = new ArrayList<String>();
// Erzeugt eine neue ArrayList, deren Elemente alle vom Typ String sein müssen.
messages.add("Hallo Welt!");
messages.add("Das Pferd frißt keinen Gurkensalat.");
messages.add(42); // 42 ist kein String -> nicht zulässig!
Durch die Angabe des Typparameters <String>
wird sichergestellt, dass alle Einträge in der Liste messages
Strings sind und über die Attribute und Methoden der Klasse String
verfügen.
Als Typparameter kann auch eine Oberklasse angegeben werden. Diese darf auch abstrakt sein. Die Einträge der Liste dürfen dann auch einer Unterklasse angehören.
ArrayList<Number> numbers = new ArrayList<Number>();
numbers.add(42); // 42 ist ein Integer, eine Unterklasse von Number
numbers.add(Math.PI); // Pi ist ein Double, eine Unterklasse von Number
numbers.add(new BigInteger("3985729085613846581756039485280345601394650198650128365128640198651928465104395630956812098561309485632804561308456")); //Diese sehr große Zahl ist ein BigInteger, eine Unterklasse von Number
Auch hier kann durch die Angabe des Typparameters sichergestellt werden, dass die Liste nur Number
s enthält.
Bei der eigenen Implementierung einer generischen Klasse müssen die Bezeichnungen der Typparameter in der Klassendefinition angegeben werden. Hierfür sind einzelne Großbuchstaben üblich. Der generische Typparameter darf kein existierender Datentyp sein. Dieser Typparameter kann auch in Methodensignaturen als Parameter oder Rückgabetyp angegeben werden.
Diese Klasse implementiert 2-Tupel, deren beide Bestandteile unterschiedliche Typen haben dürfen:
public class Pair<A,B>
{
private A first;
private B second;
public Pair(A fst, B snd)
{
this.first = fst;
this.second = snd;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
public void setFirst(A fst) {
this.first = fst;
}
public void setSecond(B snd) {
this.second = snd;
}
}
Mit dieser Klasse können beliebige Tupel aus zwei Elementen erzeugt werden:
Pair<String, Integer> strasseMitHausnummer = new Pair<String, Integer>("Parkstraße", 1);
String strasse = strasseMitHausnummer.getFirst();
Integer hausnummer = strasseMitHausnummer.getSecond();
Die Typparameter können auch ineinander geschachtelt werden:
ArrayList<Pair<String, Integer>> adressen = new ArrayList<Pair<String,Integer>>();
adressen.add(new Pair<String, Integer>("Parkstraße", 1));
adressen.add(new Pair<String, Integer>("Brachenfelder Straße", 23));
adressen.add(new Pair<String, Integer>("Wrangelstraße", 12));
adressen
ist eine Liste, die wiederum Paare aus Integer
und String
enthält.