Übungsaufgaben
Zehn Übungen zum Klicken, Ziehen und Knobeln — von AFB I bis AFB III. Die Aufgaben übertragen das Muster der Bücherverwaltung (eine Klasse für das einzelne Ding, eine für die Sammlung) auf andere Verleih-Projekte. Wenn du hängst, helfen dir die gestuften Tipps.
Die Pausenausleihe verleiht Brettspiele. Geplant sind zwei Klassen: Spiel (ein einzelnes Brettspiel) und Spieleschrank (verwaltet alle Spiele). In welche Klassenkarte gehört welche Zeile?
Spiel. Was über alle Spiele Bescheid wissen muss — suchen, zählen, hinzufügen —, gehört in die Sammelklasse mit der Liste. Die Liste ist zugleich die Assoziation zwischen beiden Klassen.Fünf Behauptungen über das Vorgehen in einem Verwaltungsprojekt wie dem Spieleschrank:
Spiel zuerst, dann hinzufuegen, dann suche, dann alles, was auf suche aufbaut. Rückgabewerte wie null und false sind dabei keine Fehler, sondern Antworten („nicht gefunden“, „ging nicht“).Die Schule verleiht Laptops aus einem Laptopwagen. Finde zu jeder Zeile der Klassenkarte Laptopwagen die passende Java-Zeile.
ArrayList<Laptop>. Der Rückgabetyp von suche ist eine Klasse (Laptop) — die Methode liefert ein ganzes Objekt oder null. Im Konstruktor wird die leere Liste erzeugt: laptops = new ArrayList<>();.Das Repair-Café verleiht Werkzeuge. Die Klasse Werkzeugkiste hat das Attribut ArrayList<Werkzeug> werkzeuge; jedes Werkzeug hat getName(). Ergänze die Suche — zwei Bausteine bleiben übrig.
public Werkzeug suche(String name) {
for ( w : werkzeuge) {
if (w.getName().(name)) {
w;
}
}
return ;
}
Werkzeug-Objekt nacheinander aus der Liste. Sobald der Name passt, beendet return w; die ganze Methode — die übrigen Werkzeuge werden gar nicht mehr angeschaut. Erst wenn die Schleife durch ist, steht fest: nicht gefunden, also null. false passt nicht, weil die Methode ein Werkzeug liefern muss.werkzeuge? Genau dieser Typ steht vor der Schleifenvariable.Werkzeug. Welcher Wert bedeutet bei Objekten „keins gefunden“?Im Fundus hängen fünf Kostüme: Pirat, Hexe, Drache, Ritter und Roboter — keines ist ausgeliehen. suche funktioniert wie in A4; anzahlVerfuegbar() zählt die nicht ausgeliehenen Kostüme.
public boolean ausleihen(String name) {
Kostuem k = suche(name);
if (k == null || k.istAusgeliehen()) {
return false;
}
k.setAusgeliehen(true);
return true;
}
fundus.ausleihen("Pirat");
fundus.ausleihen("Hexe");
fundus.ausleihen("Pirat");
fundus.ausleihen("Drachen");
fundus.suche("Hexe").setAusgeliehen(false);
-
anzahlVerfuegbar()vor der ersten Zeile -
Wie viele der vier
ausleihen-Aufrufe lieferntrue? -
anzahlVerfuegbar()nach Zeile 4 -
anzahlVerfuegbar()am Ende
suche liefert null, und die Bedingung k == null fängt das ab, bevor k.istAusgeliehen() abstürzen könnte. Die letzte Zeile gibt die Hexe zurück: 4 verfügbar. (Mit java geprüft.)ausleihen liefert false in zwei Fällen: nicht gefunden — oder schon ausgeliehen. Vergleiche die Namen Buchstabe für Buchstabe.Bring die Arbeitsschritte des Projekts in eine sinnvolle Reihenfolge — jeder Schritt baut auf dem vorigen auf.
Spiel und Spieleschrank entwerfen
Spiel mit Konstruktor und Gettern schreiben, ein Objekt erzeugen und die Werte ausgeben
Spieleschrank mit Liste und hinzufuegen schreiben, drei Spiele hinzufügen
suche schreiben, mit einem vorhandenen und einem fehlenden Titel testen
ausleihen mithilfe von suche schreiben und zweimal dasselbe Spiel ausleihen
anzahlVerfuegbar schreiben und vor und nach dem Ausleihen vergleichen
Spiel keine Liste von Spielen, ohne Spiele in der Liste nichts zu suchen, ohne suche kein ausleihen, und anzahlVerfuegbar lässt sich erst sinnvoll testen, wenn man etwas ausleihen kann. Nach jedem Schritt wird sofort getestet.Wiederholung aus 1.2.4 und 1.3.1 (Kapselung, ArrayList): Der Laptopwagen aus A3 hat das private Attribut laptops; Laptop hat nur den Konstruktor Laptop(int nummer). Im Wagen steht ein Laptop mit Nummer 7, einen mit Nummer 99 gibt es nicht. Was passiert bei diesen Zeilen in main?
laptops has private access (von außen nur über hinzufuegen), "7" ist ein String statt int, laptop klein gibt es nicht (cannot find symbol), und ohne eigenen parameterlosen Konstruktor scheitert new Laptop(). Der Absturz: suche(99) liefert null, und an null kann man keine Methode aufrufen — NullPointerException. Deshalb prüft man das Suchergebnis vorher mit != null. (Alle Zeilen mit javac/java geprüft.)suche, wenn es die Nummer nicht gibt — und was passiert, wenn man daran eine Methode aufruft?Die Methode anzahlVerfuegbar() im Spieleschrank soll zählen, wie viele Spiele gerade nicht ausgeliehen sind. Drei Zeilen sind falsch: einer ist ein Übersetzungsfehler, einer ein Absturz, einer zählt das Falsche.
not a statement — die Summe wird berechnet, aber nirgends gespeichert. Zeile 3 läuft mit <= einen Schritt zu weit: get(size()) wirft eine IndexOutOfBoundsException. Zeile 4 zählt ohne ! genau die falschen Spiele — die ausgeliehenen. Eine for-each-Schleife for (Spiel s : spiele) hätte den Indexfehler gar nicht erst möglich gemacht. (Mit javac/java geprüft.)get(3)?In der Werkzeugkiste aus A4 liegen Akkuschrauber, Lötkolben, Heißklebepistole und Multimeter; die Heißklebepistole ist bereits ausgeliehen. ausleihen und anzahlVerfuegbar funktionieren wie beim Kostümfundus (A5). Die Tests laufen nacheinander. Welches Ergebnis muss jeder Test liefern, damit er „bestanden“ ist?
1. suche("Akkuschrauber") →
2. suche("akkuschrauber") →
3. ausleihen("Lötkolben") →
4. gleich danach noch einmal ausleihen("Lötkolben") →
5. ausleihen("Heißklebepistole") →
6. anzahlVerfuegbar() →
equals unterscheidet Groß und Klein), doppeltes Ausleihen (4), schon vorher ausgeliehen (5). Am Ende sind nur noch Akkuschrauber und Multimeter da: 2. Wer das erwartete Ergebnis vor dem Test aufschreibt, merkt sofort, wenn das Programm etwas anderes liefert. (Testreihe mit java geprüft.)suche liefert ein Objekt oder null, ausleihen einen Wahrheitswert. Und wie genau vergleicht equals?Finn hat die Suche im Kostümfundus „vereinfacht“. Im Fundus hängen in dieser Reihenfolge: Pirat, Hexe, Drache, Ritter.
public Kostuem suche(String name) {
for (Kostuem k : kostueme) {
if (k.getName().equals(name)) {
return k;
} else {
return null;
}
}
return null;
}
Welche Aussagen stimmen?
else gibt schon beim ersten nicht passenden Kostüm auf. Nur wer ganz vorne hängt, wird gefunden — ein Fehler, den ein Test mit dem ersten Element nie aufdeckt. Deshalb immer auch das letzte und ein fehlendes Element testen. Das letzte return null; ist nötig: Bei einer leeren Liste läuft die Schleife gar nicht, und ohne diese Zeile meldet javac missing return statement. (Verhalten mit java geprüft.)suche("Hexe") durch: Was passiert beim ersten Durchlauf mit dem Piraten?return beendet sofort die ganze Methode — egal ob im if oder im else. Und was macht die Schleife bei einer leeren Liste?