Inhaltsverzeichnis
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 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> { T anfang; void add(T element){ ... } T getFirst(){ ... } }
Eine Liste zum Speichern von Kunde
-Objekten instanziert man dann so:
Liste<Kunde> kundenliste = new Liste<Kunde>(); // Wegen Type-inference geht auch: List<Kunde> 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 Unit Test.