Übungsaufgaben
Zehn Übungen zum Klicken, Ziehen und Knobeln — von AFB I bis AFB III. Jede Übung gibt dir sofort Rückmeldung; wenn du hängst, helfen dir die gestuften Tipps.
Ein Fitnessstudio plant seine Kurse mit diesem Klassendiagramm. Welche Aussagen stimmen?
- - titel: Zeichenkette
- - plaetze: Ganzzahl
- - leitung: Trainerin
- c Kurs(titel: Zeichenkette, leitung: Trainerin)
- + getLeitung(): Trainerin
- + setLeitung(t: Trainerin)
- + getTitel(): Zeichenkette
- - name: Zeichenkette
- - telefon: Zeichenkette
- c Trainerin(name: Zeichenkette)
- + getName(): Zeichenkette
leitung der Klasse Kurs — in Trainerin gibt es kein Attribut vom Typ Kurs, also kennt die Trainerin ihre Kurse nicht. Die Kardinalitäten lesen sich so: Ein Kurs wird von genau einer Trainerin geleitet, eine Trainerin kann n Kurse leiten. Gespeichert wird nur ein Verweis, keine Kopie: Ändert die Trainerin ihre Telefonnummer, sehen das alle Kurse, die sie kennen. Typischer Fehler: getLeitung() mit dem Namen verwechseln — sie liefert das ganze Objekt; den Namen bekommt man erst mit k.getLeitung().getName().Die Theater-AG verwaltet ihre Aufführung mit einer Klasse Rolle. Es gibt außerdem die Klassen Person und Kostuem. Ordne die Einträge der Klassenkarte zu.
name gehört zu den Standard-Datentypen, auch wenn String in Java eine Klasse ist. Typischer Fehler: getDarsteller(): Person zu den Beziehungen legen — die Methode nutzt die Beziehung, gespeichert wird sie aber im Attribut. Übrigens: Zwei Attribute vom Typ Person heißt, eine Rolle kann zwei Personen kennen.Im Schulkalender kennt jeder Termin den Raum, in dem er stattfindet. Die Klasse Raum hat den Konstruktor Raum(nummer: Zeichenkette) und die Methode getNummer(). Setze ein — ein Wort bleibt übrig.
- - titel: Zeichenkette
- - ort: Raum
- c Termin(titel: Zeichenkette, ort: Raum)
- + getOrt(): Raum
- + setOrt(r: Raum)
- - nummer: Zeichenkette
- c Raum(nummer: Zeichenkette)
- + getNummer(): Zeichenkette
In Java wird die Beziehung zum Attribut private ort;. Im Konstruktor stellt .ort = ort; die Beziehung her. Den Raum muss es vorher schon geben — ein Raum-Objekt entsteht nur mit . Hat ein Termin noch keinen Raum (Kardinalität 0..1), dann ist ort gleich . Die Raumnummer eines Termins t erfährt man mit t.().getNummer().
String bleibt übrig — und genau das ist der typische Fehler: Wer private String ort; schreibt, speichert nur einen Text. Der Termin kennt dann kein Raum-Objekt und kann dessen Methoden nicht nutzen. Die Kardinalität 0..1 heißt: Ein Termin kennt höchstens einen Raum, darf aber auch (noch) keinen kennen — dann steht null im Attribut.Ein Mobilfunkanbieter modelliert: Jedes Smartphone kennt seinen Tarif (Name, Datenvolumen in GB, Getter und setVolumen).
Tarif basis = new Tarif("Basic", 5);
Tarif max = new Tarif("Max", 40);
Smartphone s1 = new Smartphone("Lina", basis);
Smartphone s2 = new Smartphone("Tom", basis);
Smartphone s3 = new Smartphone("Eda", null);
s3.getTarif().getName() muss man sicher sein, dass kein Glied null ist.Beim Einchecken wird jeder Koffer einem Flug zugeordnet (Kardinalität: ein Koffer kennt genau einen Flug). Die Klasse Flug hat den Konstruktor Flug(nummer, ziel) und die Methode getZiel(). Verbinde jede Aufgabe mit dem passenden Java-Baustein.
k.getFlug().getZiel() heißt Delegation: Der Koffer kennt das Ziel selbst nicht, er fragt seinen Flug. Häufige Verwechslung: der Getter getFlug() und der Delegationsaufruf — der Getter liefert das Objekt, erst die Kette liefert das Ziel.Ein E-Scooter kennt seinen Wechselakku. Beim Fahren wird der Akku in einer Schleife (Kapitel 1) entladen, bis er zu schwach ist.
public class Akku {
private int ladung;
public Akku(int ladung) {
this.ladung = ladung;
}
public int getLadung() {
return ladung;
}
public void entladen(int prozent) {
ladung = ladung - prozent;
}
}
public class Scooter {
private Akku akku;
private int km;
public Scooter(Akku akku) {
this.akku = akku;
km = 0;
}
public void fahren() {
while (akku.getLadung() >= 15) {
akku.entladen(15);
km = km + 2;
}
}
public int getKm() {
return km;
}
}
Akku a = new Akku(80); Scooter s = new Scooter(a); s.fahren(); Scooter t = new Scooter(a); t.fahren();
Welchen Wert hat s.getKm() + t.getKm()?
Beim Staffellauf kennt jede Läuferin bzw. jeder Läufer den Nachfolger, dem der Stab übergeben wird (0..1 — der letzte hat keinen). Die Klasse Laeufer hat den Konstruktor Laeufer(name, nachfolger) und die Methoden getName() und getNachfolger(). Bringe die Zeilen in die einzige Reihenfolge, in der das Programm übersetzt wird.
Laeufer d = new Laeufer("Dana", null);
Laeufer c = new Laeufer("Cem", d);
Laeufer b = new Laeufer("Ben", c);
Laeufer a = new Laeufer("Ada", b);
String name = a.getNachfolger().getNachfolger().getName();
null), dann Cem, Ben und zuletzt Ada. Die letzte Zeile folgt zweimal der Beziehung: Ada → Ben → Cem, also ist name gleich "Cem". Typischer Fehler: mit Ada anfangen, weil sie zuerst läuft — dann ist b noch gar nicht deklariert.Ein Eisenbahnverkehrsunternehmen ordnet seinen Zügen Loks zu. Wie viele Wagen ein Zug ziehen darf, hängt von der Leistung seiner Lok ab.
public class Lok {
private String name;
private int leistung;
public Lok(String name, int leistung) {
this.name = name;
this.leistung = leistung;
}
public int getLeistung() {
return leistung;
}
public void drosseln(int kw) {
leistung = leistung - kw;
}
}
public class Zug {
private String linie;
private Lok lok;
public Zug(String linie, Lok lok) {
this.linie = linie;
this.lok = lok;
}
public void setLok(Lok lok) {
this.lok = lok;
}
public Lok getLok() {
return lok;
}
public int maxWagen() {
if (lok == null) {
return 0;
}
return lok.getLeistung() / 500;
}
}
Lok l1 = new Lok("E-103", 6000);
Lok l2 = new Lok("V-200", 2000);
Zug z1 = new Zug("IC 41", l1);
Zug z2 = new Zug("RE 7", l1);
Zug z3 = new Zug("RB 12", null);
z2.setLok(l2);
z3.setLok(z1.getLok());
l1.drosseln(1000);
-
Rückgabewert von
z3.maxWagen()direkt nach dem Erzeugen von z3 Wagen -
Rückgabewert von
z2.maxWagen()am Ende Wagen -
Rückgabewert von
z3.maxWagen()am Ende Wagen -
Summe von
maxWagen()über alle drei Züge am Ende Wagen
null-Prüfung den Aufruf ab: 0. z2 bekommt die Lok l2: 2000 / 500 = 4. z3.setLok(z1.getLok()) übergibt keine Kopie, sondern einen Verweis auf dieselbe Lok l1. Das Drosseln wirkt daher auf z1 und z3: je 5000 / 500 = 10. Summe 10 + 4 + 10 = 24. Typische Fehler: 12 für z3 (als hätte z3 eine eigene Lok mit der alten Leistung) oder 36 (übersehen, dass z2 umgestellt wurde).Eine Praxissoftware soll speichern, welchen Hausarzt ein Patient hat (0..1). Neue Patienten haben zunächst keinen Hausarzt. Die Klasse Arzt ist fertig:
- - name: Zeichenkette
- c Arzt(name: Zeichenkette)
- + getName(): Zeichenkette
In der Klasse Patient stecken drei Fehler — zwei Übersetzungsfehler und einer, der zu falschem Verhalten führt.
null-Prüfung in getArztName ist richtig und wichtig: Ohne sie gäbe es bei Patienten ohne Hausarzt eine NullPointerException. Der Fehler in setHausarzt ist der tückischste — das Programm läuft, aber jeder Patient meldet für immer „kein Hausarzt“.Eine Geocaching-Runde besteht aus Stationen; jede Station kennt die nächste. Nach der letzten geht es wieder zur ersten.
public class Station {
private int nummer;
private int punkte;
private Station weiter;
public Station(int nummer, int punkte) {
this.nummer = nummer;
this.punkte = punkte;
weiter = null;
}
public void setWeiter(Station weiter) {
this.weiter = weiter;
}
public Station getWeiter() {
return weiter;
}
public int getNummer() {
return nummer;
}
public int getPunkte() {
return punkte;
}
}
Station s1 = new Station(1, 2); Station s2 = new Station(2, 3); Station s3 = new Station(3, 1); s1.setWeiter(s2); s2.setWeiter(s3); s3.setWeiter(s1); s2 = s3;
Welchen Wert liefert jeder Ausdruck nach diesen Zeilen?
s1.getWeiter().getNummer()
s2.getWeiter().getNummer()
s1.getWeiter().getWeiter().getWeiter().getNummer()
s3.getWeiter().getWeiter().getPunkte()
s1.getWeiter().getPunkte() + s2.getPunkte()
s2 = s3; ändert nur die Variable s2 — sie zeigt jetzt auf Station 3. Die Beziehungen zwischen den Objekten bleiben unverändert: Station 1 kennt weiterhin Station 2, obwohl keine Variable mehr auf Station 2 zeigt. Also liefert s1.getWeiter() immer noch Station 2 (Nummer 2, 3 Punkte), während s2.getWeiter() jetzt Station 1 ist. Dreimal weiter führt einmal im Kreis zurück zu Station 1. Wer bei Zeile 2 den Wert 3 gewählt hat, hat s2 noch als Station 2 gelesen.