Sie modellieren auf diesem Blatt einen kleinen Zoo in Java.
Zunächst steht das Erstellen einer Typhierarchie mit sealed types / records und der Einsatz von Generics im Vordergrund. Anschließend erweitern Sie dieses Modell um:
- sinnvolle Zustandsänderungen (Tiere aufnehmen, umsetzen, abgeben),
- Logging der ausgeführten Aktionen,
- sowie den Einsatz der Stream-API.
Ziel ist es, dass Sie die im Kurs behandelten Konzepte eigenständig auf ein kleines, aber zusammenhängendes Beispiel anwenden.
Modellieren Sie die im Diagramm gezeigte stark vereinfachte Hierarchie von Tierarten:

Nutzen Sie dabei sealed interfaces.
Erstellen Sie für jedes dieser Interfaces jeweils zwei Record-Klassen,
die konkrete Mitglieder der jeweiligen Tier-Klasse bzw. -Familie1
repräsentieren und die jeweils das Interface implementieren.
Beispielsweise könnte eine Forelle eine Art in der Klasse der Fische
sein, d.h. die Java-Klasse Trout könnte das Interface Fish
implementieren.
Geben Sie den Tieren jeweils mindestens einen Namen (z.B. String name)
als Attribut.
Important
Hinweis: Nutzen Sie permits in Ihren sealed-Deklarationen so,
dass nur die von Ihnen gewünschten Implementierungen erlaubt sind.
Tip
Hinweis: Da wir hier keine Java-Module verwenden, müssen alle
Klassen und Interfaces, die in einer sealed-Hierarchie über
permits verbunden sind, im gleichen Package liegen, z.B.
zoo.animal. Unterpakete wie zoo.animal.birds sind deshalb für
sealed hier nicht möglich.
Definieren Sie zur Repräsentation eines Geheges eine generische Klasse
Enclosure mit einer Typ-Variablen. Stellen Sie durch geeignete
Beschränkung der Typ-Variablen sicher, dass nur Gehege mit von Animal
abgeleiteten Typen gebildet werden können.
Anforderungen:
-
Jedes Gehege hat:
- einen eindeutigen Namen (
String name), sowie - eine geeignete Sammlung seiner Bewohner.
- einen eindeutigen Namen (
-
Kein Tier kann in einem Gehege mehrfach vorkommen. Lösen Sie dies durch die Auswahl einer geeigneten inneren Datenstruktur und begründen Sie Ihre Wahl kurz.
-
Implementieren Sie Methoden wie:
boolean add(T animal)boolean remove(T animal)List<T> getInhabitants()
Definieren Sie spezialisierte Gehege, die die Typhierarchie widerspiegeln:
- ein
Aquarium, welches vonFishabgeleitete Tiere beherbergen kann, - ein
Terrariumfür vonReptileabgeleitete Tiere, - ein
MammalHousefür Säugetiere (Mammal), sowie - ein
CatHouse, welches nur Objekte einer konkreten vom InterfaceCatabgeleiteten Klasse zulässt.
Implementieren Sie eine Klasse Zoo, welche eine Liste mit Tier-Gehegen
verwaltet.
Implementieren Sie folgende Methoden:
-
addEnclosurezum Hinzufügen eines neuen Tier-Geheges -
getEnclosuresliefert eine Liste aller Gehege im Zoo zurück -
findEnclosureByNamegibt das erste gefundene Gehege mit diesem Namen aus dem Zoo zurück (odernull, wenn nicht gefunden) -
getAllAnimalsgibt eine Liste aller Tiere in allen Gehegen zurück -
getAllMammalsgibt eine Liste aller Tiere in allen Gehegen zurück, deren Typ eine Subclass-Beziehung zuMammalhat -
getAnimalsByPredicatezum Zurückgeben aller Tiere in den Gehegen, die dem übergebenen PrädikatPredicate<Animal>genügen -
countAnimalsByType, die für jeden Tiertyp zählt, wieviele Objekte dieser Art im Zoo sind -
getOvercrowdedEnclosuresgibt eine Liste aller Gehege zurück, die mehr Tiere enthalten, als der Parameter angibt -
String summary()erstellt eine kurze textuelle Zusammenfassung des aktuellen Zoo-Zustands erzeugt, z.B.:Zoo mit 3 Gehegen und 12 Tieren: 5 Mammals, 4 Birds, 3 Fish
Nutzen Sie dabei die Stream-API, z.B. zum Durchlaufen aller Gehege
und Tiere. Nutzen Sie hier geeignet filter, map, flatMap, toList
und/oder collect mit Collectors.groupingBy, Collectors.toList,
Collectors.joining, Collectors.counting o.ä.
Important
Wählen Sie die Parameter und Rückgabetypen geeignet und begründen Sie Ihre Wahl kurz.
Tip
Wenn Sie bereits Optional<T> kennen, können Sie bei
findEnclosureByName gern damit arbeiten. Ansonsten geben Sie beim
Nichtfinden des gesuchten Geheges zunächst klassisch null zurück.
Tip
Zu jeder Klasse können Sie sich das passende Class<T>-Objekt geben
lassen: MyClass.class. Darauf stehen Ihnen dann Operationen wie
boolean isInstance(Object obj) oder T cast(Object obj) zur
Verfügung.
Fügen Sie nun Logging mit java.util.logginghinzu, um alle
Zoo-Aktionen von außen nachvollziehbar zu machen.
Legen Sie dazu in Zoo einen Logger an und loggen Sie in jeder public
Zoo-Methode:
- auf Level
INFOden Start/Aufruf der Methode mit den relevanten Parametern, - auf Level
FINEeine kurze Zustandszusammenfassung nach erfolgreicher Ausführung einer Methoden (z.B. Anzahl Tiere im Zoo), - auf Level
WARNING, wenn ein angefordertes Tier oder Gehege nicht gefunden wird, und - auf Level
SEVEREbei schwerwiegenden Inkonsistenzen.
Demonstrieren Sie in einer Demo-Main, wie Sie das Log-Level für Ihren Logger gezielt umschalten können.
Beantworten Sie die folgenden Fragen kurz und prägnant (Stichpunkte sind
ausreichend). Geben Sie Ihre Antworten zusammen mit Ihrem Code in Ihrem
Repo ab (z.B. im README.md).
- Generics
- Wo helfen Ihnen die Generics im Zoo-Szenario, Fehler bereits zur Compile-Zeit zu vermeiden?
- Nennen Sie ein Beispiel aus Ihrer Implementierung, bei dem falsche Tier-Gehege-Kombinationen durch den Typchecker verhindert werden.
- Logging
- Warum ist systematisches Logging mit einem Logger und Log-Leveln
für ein Zoo-Management-System sinnvoller als Ausgaben mit
IO.println? - In welchen Situationen würden Sie in Ihrem System die Log-Level
INFO,WARNINGund ggf.SEVEREverwenden?
- Warum ist systematisches Logging mit einem Logger und Log-Leveln
für ein Zoo-Management-System sinnvoller als Ausgaben mit
- Streams
- Wo haben Ihnen Streams im Vergleich zu klassischen Schleifen beim Formulieren Ihrer Abfragen geholfen? Wo wurde es eher unübersichtlich?
- Bearbeitung: Einzelbearbeitung
- Abgabe Post Mortem im ILIAS: bis 29. Juni, 08:00 Uhr
- Vorstellung im Praktikum: 29. Juni / 01. Juli
Unless otherwise noted, this work is licensed under CC BY-SA 4.0.
Last modified: fe51f8b 2026-06-18 update b07 (S26: Generics, Sealed Types, Stream-API, Logging) (#1133)
Footnotes
-
Ok, wir machen hier Informatik. Vermutlich ist die Biologie nicht ganz korrekt ;-) ↩
