Ü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.
Die App eines Fitnesstrackers enthält diese Deklarationen. Was steht jeweils in der Variablen selbst?
int, double, boolean und char speichern den Wert direkt. Alles andere ist ein Objekttyp — die Variable enthält nur einen Verweis auf das Objekt. Typische Fehler: String zu den Werten legen, weil man Zeichenketten so bequem wie Zahlen schreibt, und int[] übersehen: Eine Reihung ist auch ein Objekt, selbst wenn sie Ganzzahlen enthält (Kapitel 2). Und reserve ist eine Referenzvariable, die gerade auf nichts zeigt.Ein digitales Adressbuch speichert Kontakte. Welche Aussagen über diese drei Zeilen stimmen?
Kontakt k1 = new Kontakt("Mila", "0151 223344");
Kontakt k2 = k1;
Kontakt k3 = new Kontakt("Mila", "0151 223344");
new erzeugt Objekte — zwei new, zwei Objekte. k2 = k1 kopiert die Referenz, nicht das Objekt: k2 ist ein zweiter Name (Alias) für dasselbe Objekt. == vergleicht bei Objekten, ob zwei Referenzen auf dasselbe Objekt zeigen — gleiche Werte reichen nicht. Und k1 = null; ändert nur die Variable k1; k2 verweist weiter auf das Objekt.Ein Smartphone-Wecker speichert die Schlummerzeit als Zahl und den Wecker selbst als Objekt. Setze die Fachbegriffe ein — einer bleibt übrig.
int schlummer = 9;
Wecker w = new Wecker("06:45");
Wecker morgen = w;
Wecker urlaub = null;
Die Variable schlummer speichert direkt den 9. Die Variable w speichert dagegen eine auf ein Wecker-Objekt. Das Objekt selbst entsteht erst durch . Die Variable urlaub verweist auf kein Objekt, sie hat den Wert . Nach Wecker morgen = w; ist morgen nur ein zweiter Name für dasselbe Objekt — ein .
equals bleibt übrig: Es vergleicht den Inhalt zweier Objekte (etwa zweier Zeichenketten) und kommt in diesen vier Zeilen gar nicht vor. Häufiges Missverständnis: morgen sei eine Kopie des Weckers. Stellt man über morgen die Weckzeit um, klingelt aber auch w zur neuen Zeit — es ist ja dasselbe Objekt.Ein Router prüft das eingegebene WLAN-Passwort. Zum Test werden diese Zeichenketten angelegt (new String(...) erzeugt ausdrücklich ein neues String-Objekt, so wie es auch beim Einlesen einer Tastatureingabe geschieht):
String passwort = "LUX7";
String eingabe = new String("LUX7");
String kopie = passwort;
equals vergleichen. == prüft bei Objekten nur, ob beide Variablen auf dasselbe Objekt zeigen. Das kann bei zwei gleichen String-Literalen zufällig true liefern und verleitet so zu einem Fehler, der erst bei echten Eingaben auffällt.Die Klasse Wagen eines Zuges hat den Konstruktor Wagen(plaetze: Ganzzahl) sowie getPlaetze() und setPlaetze(p). Die Zeilen links werden nacheinander ausgeführt. Verbinde jede Zeile mit ihrer Wirkung.
plaetze ist eine int-Variable und behält den kopierten Wert 60, auch wenn das Objekt danach auf 56 geändert wird. Über den Alias v ändert man dagegen das gemeinsame Objekt — w sieht die Änderung sofort. Nach w = new Wagen(80); zeigen w und v auf verschiedene Objekte, also liefert w == v false.Ein Kanuverleih erhöht seine Preise. Die Hilfsklasse bekommt einmal eine einzelne Zahl und einmal eine Reihung aus Kapitel 2 übergeben:
public class Tarifrechner {
public void erhoehen(int preis) {
preis = preis + 5;
}
public void erhoehenAlle(int[] preise) {
for (int i = 0; i < preise.length; i++) {
preise[i] = preise[i] + 5;
}
}
}
Tarifrechner v = new Tarifrechner();
int grundpreis = 12;
int[] tarife = {12, 18, 25};
v.erhoehen(grundpreis);
v.erhoehenAlle(tarife);
v.erhoehen(tarife[0]);
Welchen Wert hat grundpreis + tarife[0] + tarife[2] am Ende?
int ist das der Wert 12 — erhoehen ändert nur seine lokale Kopie preis, grundpreis bleibt 12. Bei int[] ist der Inhalt eine Referenz: erhoehenAlle arbeitet auf derselben Reihung, tarife wird zu {17, 23, 30}. Der dritte Aufruf übergibt wieder nur den Wert tarife[0] = 17 und ändert nichts. Also 12 + 17 + 30 = 59. Häufige Fehler: 69 (jede Erhöhung wirkt) oder 49 (auch die Reihung bleibt unverändert).Eine Schach-Lern-App speichert zu jeder Figur die Spalte (1 bis 8). ziehe(felder) addiert die Felder zur Spalte, getSpalte() liefert sie.
Figur a = new Figur("Turm", 1);
Figur b = new Figur("Springer", 2);
Figur c = new Figur("Laeufer", 3);
Figur e = new Figur("Koenig", 6);
Figur d = a;
d.ziehe(3);
d = b;
d.ziehe(3);
b = c;
b.ziehe(-1);
c = new Figur("Dame", 8);
c.ziehe(-1);
Sortiere die Aufrufe nach ihrem Rückgabewert am Ende — der kleinste zuerst.
b.getSpalte()
a.getSpalte()
d.getSpalte()
e.getSpalte()
c.getSpalte()
a.ziehe aufgerufen wurde — d war aber ein Alias für a.Ein Fahrradverleih zählt die gefahrenen Kilometer jedes Rades.
public class Leihrad {
private String nummer;
private int km;
public Leihrad(String nummer) {
this.nummer = nummer;
km = 0;
}
public void fahren(int strecke) {
km = km + strecke;
}
public int getKm() {
return km;
}
}
Leihrad r1 = new Leihrad("R-07");
Leihrad r2 = new Leihrad("R-12");
Leihrad r3 = r1;
r3.fahren(12);
r1.fahren(5);
r2 = r3;
r2.fahren(8);
r3 = new Leihrad("R-20");
r3.fahren(4);
-
Rückgabewert von
r1.getKm()direkt nach der Zeiler1.fahren(5);km -
Rückgabewert von
r2.getKm()am Ende km -
Wie viele
Leihrad-Objekte wurden insgesamt erzeugt? Objekte - Wie viele der drei Variablen verweisen am Ende auf das Rad „R-07“? Variablen
r2 = r3; zeigt auch r2 auf R-07 — die 8 km kommen dazu: 25. Das Rad R-12 hat keine Variable mehr, die darauf zeigt, existiert aber als drittes Objekt (neben R-07 und R-20). Am Ende zeigen r1 und r2 auf R-07, r3 auf R-20. Häufiger Fehler: r2.getKm() = 8, weil man meint, r2 sei noch das Rad R-12.Ein Vokabeltrainer soll drei unabhängige Vokabeln anlegen: Hund/dog, Katze/cat und Maus/mouse. Danach bekommt der Lernende einen Punkt, wenn seine Eingabe antwort (zur Laufzeit eingetippt) zur ersten Vokabel passt. Die Klasse Vokabel hat den Konstruktor Vokabel(deutsch, englisch), Getter und Setter. Drei Zeilen sind falsch — eine davon lässt sich gar nicht übersetzen.
new. Zeile 6 kompiliert ebenfalls, liefert bei echter Eingabe aber fast immer false.Oma hilft beim Sparen. Jede Zeile unten startet neu mit Sparschwein p = new Sparschwein(); int bar = 1; Oma o = new Oma(); Welchen Wert liefert der letzte Ausdruck der Zeile? Achte genau darauf, was in den Methoden mit dem Parameter passiert.
public class Sparschwein {
private int betrag;
public Sparschwein() {
betrag = 0;
}
public void einwerfen(int euro) {
betrag = betrag + euro;
}
public int getBetrag() {
return betrag;
}
}
public class Oma {
public void schenken(Sparschwein s) {
s.einwerfen(1);
}
public void neuesSchwein(Sparschwein s) {
s = new Sparschwein();
s.einwerfen(3);
}
public void erhoehen(int zahl) {
zahl = zahl + 2;
}
}
o.schenken(p); p.getBetrag()
o.neuesSchwein(p); p.getBetrag()
o.erhoehen(bar); bar
Sparschwein q = p; o.schenken(q); o.schenken(p); p.getBetrag()
p.einwerfen(4); o.neuesSchwein(p); p.getBetrag()
s bekommt eine Kopie der Referenz. Über diese Kopie kann schenken das gemeinsame Objekt verändern. neuesSchwein biegt dagegen nur seine lokale Kopie auf ein neues Schwein um — p merkt davon nichts, die 3 Euro landen in einem Objekt, das nach der Methode niemand mehr kennt. Genauso ändert erhoehen nur seine Kopie von bar. Wer 3, 3 und 7 erwartet hat, hat „Parameter ändern“ mit „Objekt ändern“ verwechselt.