====== Generische Klassen ======
===== Problemstellung =====
Stellen Sie sich eine Klasse ''Liste'' vor, die beliebige Objekte speichern kann und beispielsweise Methoden ''add'' (hinten hinzufügen) und ''getFirst'' (erstes Element zürückliefern) besitzt:
class Liste {
void add(Object element){ ... }
Object getFirst(){ ... }
}
Die Klasse ''Object'' ist Oberklasse **aller** Klassen in Java. Damit die Liste beliebige Objekte speichern kann, muss der Parameter von ''add'' vom Typ ''Object'' sein, ebenso der Rückgabe-Datentyp von ''getFirst''. \\
Das ist aber **ungünstig**: Stellen Sie sich vor, Sie instanzieren eine Liste zum Speichern von ''Kunde''-Objekten:
Liste kundenliste = new Liste();
Sie würden sich wünschen, dass ''kundenliste.add'' nur Objekte der Klasse ''Kunde'' akzeptiert, damit Ihnen beim Programmieren kein Fehler unterlaufen kann. Außerdem möchten Sie beispielsweise schreiben können
Kunde k = kundenliste.getFirst();
Der Compiler meldet in diesem Fall aber einen Fehler, da er nicht weiß, dass in die ''kundenliste'' nur Objekte der Klasse ''Kunde'' gesteckt werden und ''kundenliste.getFirst()'' somit auch nur solche zurückliefern wird. \\ \\
Wir brauchen eine Möglichkeit, den Compiler **beim Instanzieren der Liste** darüber zu informieren, dass darin später nur Objekte der Klasse ''Kunde'' (und natürlich von Unterklassen davon) gespeichert werden sollen.
===== Generics =====
Viele Programmiersprachen bieten Möglichkeiten der [[https://en.wikipedia.org/wiki/Generic_programming|Generischen Programmierung]], d.h. Sie ermöglichen beispielsweise die Deklaration einer Klasse unter Zuhilfenahme eines allgemeinen Datentypen (z.B. ''T''), der erst beim Instanzieren festgelegt wird. In Java sieht das so aus:
class Liste {
T anfang;
void add(T element){ ... }
T getFirst(){ ... }
}
Eine Liste zum Speichern von ''Kunde''-Objekten instanziert man dann so:
Liste kundenliste = new Liste();
// Wegen Type-inference geht auch: List kundenliste = new Liste<>();
Jetzt ist alles wie gewünscht: ''kundenliste.add'' akzeptiert nur Objekte der Klasse ''Kunde'' (und Unterklassen) und
Kunde k = kundenliste.getFirst();
liefert keinen Fehler mehr.
===== Aufgabe =====
a) Schreiben Sie eine generische Klasse ''Liste'' unter Zuhilfenahme des Entwurfsmusters Kompositum, die mindestens folgende Methoden hat:
* ''T pop()'' (erstes Element entnehmen)
* ''push(T element)''(Element hinten anfügen)
* ''int size()'' (Anzahl der enthaltenen Elemente)
* ''void clear()'' (Liste leeren)
* ''void addFirst(T element)'' (vorne anfügen)
* ''T getLast()'' (letztes Element entnehmen)
b) Schreiben Sie für jede der Methoden oben mindestens einen automatisierten [[anhang:unittests:start|Unit Test.]]
[[.generics:loesung:start|Lösung]]
===== Bounded type parameters =====