Blatt 02: Zoo (Generics, Collections, Gradle)
(1 Punkt)
Dieses Blatt ist bewusst einfach gestaltet und dient zum Teil der Wiederholung Ihrer Kenntnisse aus der LV "Programmieren 1".
A02.1: Gradle (15%)
Folgen Sie der Anleitung auf gradle.org und installieren Sie Gradle auf Ihrem Rechner. Legen Sie in der Konsole ein neues Gradle-Projekt für eine Java-Applikation an (ohne IDE!). Das Build-Script soll in Groovy erzeugt und als Test-API soll JUnit4 verwendet werden.
Wie finden Sie auf der Konsole heraus, welche Tasks es gibt? Erklären Sie das Projektlayout, d.h. wo kommen beispielsweise die Java-Dateien hin?
Erklären Sie, in welche Abschnitte das generierte Buildskript unterteilt ist und welche
Aufgaben diese Abschnitte jeweils erfüllen. Gehen Sie dabei im Detail auf das Plugin
application
und die dort bereitgestellten Tasks und deren Abhängigkeiten untereinander ein.
Öffnen Sie das Projekt in Ihrer IDE. Wie können Sie hier die verschiedenen Tasks ansteuern?
Machen Sie sich Notizen, welche Sie im Praktikum nutzen dürfen, um dort das Buildskript zu erklären.
Zoo
Sie finden in den Vorgaben im Package zoo
einige Interfaces und Klassen, mit denen man
einen Zoo modellieren kann.
Laden Sie sich die Vorgaben im Browser von GitHub herunter1, entpacken Sie das Zip-File und laden Sie den Ordner als Gradle-Projekt in Ihre IDE.
A02.2: Nicht-generische Klassen (10%)
Sie finden einige Interfaces, die das Interface Animal
erweitern, beispielsweise Fish
,
Reptile
, Cat
, ...
Erstellen Sie für jedes dieser Interfaces jeweils zwei Java-Klassen, die konkrete Mitglieder
der jeweiligen Tier-Klasse bzw. -Familie2 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.
Diese Java-Klassen sollen nicht-generisch sein. Die move()
-Methode soll einfach einen String
auf der Konsole ausgeben, wie sich dieses Tier bewegen würde. Mit der getName()
-Methode soll
ein kurzer Name, beispielsweise der Tierklasse, zurückgegeben werden.
Hinweis: Die mit default
markierten Methoden in Fish
, Mammal
und Reptile
brauchen
Sie in Ihren Klassen nicht implementieren. Wir werden später im Semester noch über die
sogenannten “Default-Methoden” sprechen.
A02.3: Generische Klassen (15%)
Um Gehege zu modellieren, erstellen Sie in eine generische Klasse Habitat
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.
Es sollen (mindestens) folgende Methoden existieren:
void add(Animal animal)
zur Aufnahme eines Tieres in das Gehegevoid remove(Animal animal)
um ein Tier aus einem Gehege zu entfernenString getName()
um den Namen des Geheges zu bestimmen
Hinweis: Der Parametertyp Animal
in den Methoden muss entsprechend angepasst werden.
Jedes einzelne Tier im Gehege kann maximal einmal vorkommen. Begründen Sie die Wahl der Datenstruktur.
Legen Sie in Ihrer main()
-Methode mindestens zwei konkrete Gehege als Instanzen der neuen
generischen Klasse Habitat
an. Dabei sollen in diesen konkreten Gehegen nur jeweils
verschiedene Tiere einer "Art" (beispielweise Löwen, Hamster, ...) vorkommen. Fügen Sie einige
passende Tiere in die beiden Gehege ein.
A02.4: Generische Klassen reloaded (30%)
Für die Repräsentation eines Zoologischen Gartens mit mehreren verschiedenen Gehegen erstellen
Sie nun eine generische Klasse Zoo
mit einer Typ-Variablen. Stellen Sie durch geeignete
Beschränkung der Typ-Variablen sicher, dass nur Zoos mit von Habitat
abgeleiteten Typen
gebildet werden können.
Ein Zoo soll (mindestens) folgende Methoden besitzen:
void build(Habitat habitat)
zur Aufnahme eines neuen Geheges in den Zoovoid abandon(Habitat habitat)
um ein Gehege aus dem Zoo zu entfernenvoid visitAllHabitats()
um die Gehege in der Reihenfolge des Hinzufügens zu besuchen (d.h. ihren Namen auf der Konsole auszugeben)
Hinweis: Der Parametertyp Habitat
in den Methoden muss entsprechend angepasst werden.
Jedes Gehege gibt es pro Zoo nur maximal einmal, und die Reihenfolge des Errichtens definiert eine Ordnung auf den Gehegen. Begründen Sie die Wahl der Datenstruktur.
Legen Sie in Ihrer main()
-Methode einen konkreten Zoo als Instanz der neuen generischen
Klasse Zoo
an. Dieser Zoo soll einige Gehege für verschiedene Tiere beinhalten.
A02.5: Ableiten nicht-generischer Klassen (20%)
Leiten Sie von Zoo
eine nicht-generische Klasse Aquarium
ab. Aquarien können nur mit
Gehegen angelegt werden, deren Tiere vom Typ Fish
(oder abgeleitet) sind.
Legen Sie in Ihrer main()
-Methode ein konkretes Aquarium als Instanz der neuen
nicht-generischen Klasse Aquarium
an und gruppieren Sie darin verschiedene Fisch-"Gehege".
A02.6: DevDungeon (10%)
Klonen Sie das Projekt DevDungeon und laden Sie es in Ihrer IDE als Gradle-Projekt. Betrachten Sie das Sub-Projekt "devDungeon". Dies ist ein von einem Studierenden (@Flamtky) erstelltes Spiel mit mehreren Leveln, in denen Sie spielerisch verschiedene Aufgaben in-game und ex-game lösen müssen.
Starten Sie den DevDungeon mit ./gradlew devDungeon:runDevDungeon
. Spielen Sie sich für
diese Aufgabe durch das erste Level (Intro-Level) und machen Sie sich mit der Spielmechanik
vertraut. Sie bekommen in jedem relevanten Übergang passende Hinweise; allgemein können Sie
sich auch die kurze Anleitung "How to play" anschauen.
WICHTIG: Achten Sie bitte darauf, dass im Projektpfad keine Leerzeichen und keine Sonderzeichen (Umlaute o.ä.) vorkommen! Dies kann zu seltsamen Fehler führen. Bitte auch darauf achten, dass Sie als JDK ein Java SE 21 (LTS) verwenden.