MINT lernen

Projekt: Bücherverwaltung

Was die Bücherverwaltung kann, kann auch ein Spieleschrank, ein Laptopwagen oder ein Kostümfundus — erkennst du das Muster?

Dein Fortschritt:
0 / 0 Aufgaben
1

Ü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.

A1
Planen: Der Spieleschrank der Schule
AFB I

Die Pausenausleihe verleiht Brettspiele. Geplant sind zwei Klassen: Spiel (ein einzelnes Brettspiel) und Spieleschrank (verwaltet alle Spiele). In welche Klassenkarte gehört welche Zeile?

Ziehe jede Karte in den passenden Korb — oder wähle sie mit Enter aus und drücke dann die Ziffer des Korbs (0 legt sie zurück).
1Spiel
2Spieleschrank
Faustregel: Was ein einzelnes Spiel beschreibt, gehört in 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.
Ansatz: Frage bei jeder Zeile: Gilt das für ein einzelnes Spiel — oder braucht man dafür den Überblick über alle?
Weiter: Um zu zählen, wie viele Spiele verfügbar sind, muss man alle Spiele durchgehen.
A2
Stimmt's? — Projektregeln
AFB I

Fünf Behauptungen über das Vorgehen in einem Verwaltungsprojekt wie dem Spieleschrank:

Fünf Aussagen nacheinander. Eine falsche Einschätzung reicht — dann startest du die Serie mit „Neue Runde“ neu.
Aussage 1 von 5

Planen, dann in kleinen Schritten bauen und testen: 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“).
Ansatz: Überlege bei jeder Aussage, was passiert, wenn etwas schiefgeht: Wie erfährt das Programm davon?
Weiter: Wie viele Spiele muss die Suche im schlimmsten Fall anschauen — wenn das gesuchte ganz hinten steht oder fehlt?
A3
Memory: Der Laptopwagen
AFB I

Die Schule verleiht Laptops aus einem Laptopwagen. Finde zu jeder Zeile der Klassenkarte Laptopwagen die passende Java-Zeile.

Decke zwei Karten auf, die zusammengehören. Mit der Tastatur: Tab zur Karte, Enter aufdecken, Pfeiltasten zum Wandern.
Aus „Liste vom Typ Laptop“ wird 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<>();.
Ansatz: Achte auf den Methodennamen — er ist in Diagramm und Code gleich.
Weiter: Der Typ hinter dem letzten Doppelpunkt im Diagramm wird im Code zum Rückgabetyp vor dem Namen.
A4
Suchen im Repair-Café
AFB II

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.

Wort anklicken, dann Lücke anklicken (oder umgekehrt) — mit Tab und Enter geht es genauso. Ein Klick auf eine gefüllte Lücke legt das Wort zurück.

public Werkzeug suche(String name) {
    for ( w : werkzeuge) {
        if (w.getName().(name)) {
             w;
        }
    }
    return ;
}

Die for-each-Schleife holt jedes 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.
Ansatz: Welchen Typ haben die Elemente der Liste werkzeuge? Genau dieser Typ steht vor der Schleifenvariable.
Weiter: Der Rückgabetyp ist Werkzeug. Welcher Wert bedeutet bei Objekten „keins gefunden“?
A5
Der Kostümfundus der Theater-AG
AFB II

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);
Rechne die Kette Schritt für Schritt: Erst wenn ein Schritt stimmt, wird der nächste freigeschaltet. Enter prüft.
  1. anzahlVerfuegbar() vor der ersten Zeile
  2. Wie viele der vier ausleihen-Aufrufe liefern true?
  3. anzahlVerfuegbar() nach Zeile 4
  4. anzahlVerfuegbar() am Ende
Pirat und Hexe klappen (true). Der zweite Pirat scheitert, weil er schon ausgeliehen ist; „Drachen“ scheitert, weil es kein Kostüm mit genau diesem Namen gibt — 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.)
Ansatz: Führe eine Liste der fünf Kostüme und hake ab, welche gerade ausgeliehen sind.
Weiter: ausleihen liefert false in zwei Fällen: nicht gefunden — oder schon ausgeliehen. Vergleiche die Namen Buchstabe für Buchstabe.
A6
Schritt für Schritt zum Spieleschrank
AFB II

Bring die Arbeitsschritte des Projekts in eine sinnvolle Reihenfolge — jeder Schritt baut auf dem vorigen auf.

Ziehe die Karten in die richtige Reihenfolge — mit der Tastatur: ↑/↓ verschiebt, Shift+↑/↓ wechselt nur den Fokus.
1Klassendiagramm mit Spiel und Spieleschrank entwerfen
2Klasse Spiel mit Konstruktor und Gettern schreiben, ein Objekt erzeugen und die Werte ausgeben
3Spieleschrank mit Liste und hinzufuegen schreiben, drei Spiele hinzufügen
4suche schreiben, mit einem vorhandenen und einem fehlenden Titel testen
5ausleihen mithilfe von suche schreiben und zweimal dasselbe Spiel ausleihen
6anzahlVerfuegbar schreiben und vor und nach dem Ausleihen vergleichen
Jeder Schritt braucht den vorigen: Ohne 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.
Ansatz: Vor dem Programmieren steht die Planung. Welche Klasse kann man ganz ohne die andere testen?
Weiter: Welche Methode ruft welche andere auf? Die aufgerufene muss vorher fertig sein.
A7
Was geht in main?
AFB IIMix

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?

Ordne jede Zeile einem der drei Bereiche zu. Mit der Tastatur: Enter zum Auswählen, dann 1–3 für den Bereich, 0 zurück.
1 läuft fehlerfrei
2 Übersetzungsfehler
3 Absturz zur Laufzeit
Übersetzungsfehler: 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.)
Ansatz: Prüfe erst, was javac sieht: private Attribute, Typen der Argumente, Schreibweise der Klassen, vorhandene Konstruktoren.
Weiter: Was liefert suche, wenn es die Nummer nicht gibt — und was passiert, wenn man daran eine Methode aufruft?
A8
Fehler finden und korrigieren: Verfügbare Spiele zählen
AFB III

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.

Klicke die fehlerhaften Zeilen an und schreibe in das aufklappende Feld die korrigierte Zeile. Leerzeichen und Groß-/Kleinschreibung spielen beim Vergleich keine Rolle; Enter prüft.
Zeile 5 meldet javac als 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.)
Ansatz: Prüfe den Schleifenkopf mit einer Liste aus 3 Spielen: Welche Werte nimmt i an — und gibt es get(3)?
Weiter: Gezählt werden sollen die verfügbaren Spiele. Und eine Rechnung ohne Zuweisung verändert keine Variable.
A9
Testfälle für die Werkzeugkiste
AFB III

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?

Wähle in jedem Menü das erwartete Ergebnis und klicke dann auf „Prüfen“.

1. suche("Akkuschrauber") →

2. suche("akkuschrauber") →

3. ausleihen("Lötkolben") →

4. gleich danach noch einmal ausleihen("Lötkolben") →

5. ausleihen("Heißklebepistole") →

6. anzahlVerfuegbar() →

Ein guter Testplan prüft nicht nur den Normalfall (1, 3), sondern gerade die Grenzfälle: falsche Schreibweise (2 — 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.)
Ansatz: Führe eine Liste, welche Werkzeuge nach jedem Test ausgeliehen sind — die Tests bauen aufeinander auf.
Weiter: suche liefert ein Objekt oder null, ausleihen einen Wahrheitswert. Und wie genau vergleicht equals?
A10
Trickaufgabe: Die zu schnelle Suche
AFB IIITrick

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?

Mehrere Antworten sind richtig. Markiere alle zutreffenden und klicke dann auf „Prüfen“.
Der Trick: Das 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.)
Ansatz: Spiele suche("Hexe") durch: Was passiert beim ersten Durchlauf mit dem Piraten?
Weiter: return beendet sofort die ganze Methode — egal ob im if oder im else. Und was macht die Schleife bei einer leeren Liste?