MINT lernen

Abituraufgaben: Primitive Typen und Referenzen

Stromzähler und Kalendertermine: Wer eine Referenz kopiert, bekommt kein neues Objekt – und == fragt nur, ob es dasselbe ist.

Dein Fortschritt:
0 / 0 Aufgaben
1

Stromzähler im Mehrfamilienhaus

AFB I–II

Eine Hausverwaltung erfasst die Stromzähler eines Mehrfamilienhauses mit einer Java-Anwendung. Jeder Zähler hat eine Zählernummer und einen Zählerstand in kWh. Mit erhoehen wird ein positiver Verbrauch aufaddiert. Ein Auszubildender testet die Klasse mit dem abgebildeten Programmausschnitt. In der Variablen alt möchte er sich den alten Zählerstand „merken“, in z2 den Zähler „zum Ausprobieren“.

Material 1: Klasse Zaehler und Testausschnitt
Zaehler
  • - nummer: Zeichenkette
  • - stand: Ganzzahl
  • c Zaehler(nummer: Zeichenkette, stand: Ganzzahl)
  • + getNummer(): Zeichenkette
  • + getStand(): Ganzzahl
  • + erhoehen(kwh: Ganzzahl)
int alt = 4200;
Zaehler z1 = new Zaehler("Z-01", 4200);
Zaehler z2 = z1;
Zaehler z3 = new Zaehler("Z-01", 4200);
int neu = alt;
neu = neu + 150;
z2.erhoehen(150);
z3.erhoehen(30);
Die Methode erhoehen addiert kwh zum Stand, falls kwh > 0 gilt.
  1. Geben Sie nach Ausführung des Ausschnitts die Werte von alt, neu, z1.getStand() und z3.getStand() sowie die Ergebnisse der Vergleiche z1 == z2 und z1 == z3 an.
  2. Stellen Sie den Speicherzustand nach Ausführung des Ausschnitts dar: alle fünf Variablen mit ihrem Inhalt und alle erzeugten Objekte als Objektkarten.
  3. Erklären Sie, warum das „Merken“ mit alt gelingt, das „Ausprobieren“ mit z2 aber den Zähler z1 verändert, obwohl in beiden Fällen nur eine Zuweisung mit = verwendet wird.

Hinweise

Hinweis zu Aufgabe a)
Zähle, wie oft im Ausschnitt new steht – so viele Zähler-Objekte gibt es. Verfolge dann, welche Variable auf welches Objekt verweist.Angeben heißt: nur die Werte, keine Begründung.
Hinweis zu Aufgabe b)
Trenne zwei Bereiche: die Variablen (Name und Inhalt) und die Objekte (Objektkarten). Bei Objektvariablen steht als Inhalt ein Verweis auf eine Karte, kein Zahlenwert.
Hinweis zu Aufgabe c)
Was genau steht in alt, was steht in z1? Die Zuweisung kopiert immer den Inhalt der Variablen – überlege, was dieser Inhalt jeweils ist.

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

alt = 4200, neu = 4350, z1.getStand() liefert 4350, z3.getStand() liefert 4230, z1 == z2 ergibt true, z1 == z3 ergibt false.

Erwartungshorizont zu Aufgabe b)
VariableInhalt
alt4200
neu4350
z1Referenz auf Objekt A
z2Referenz auf Objekt A
z3Referenz auf Objekt B
A: Zaehler
  • nummer = "Z-01"
  • stand = 4350
B: Zaehler
  • nummer = "Z-01"
  • stand = 4230

Es gibt genau zwei Objekte (zweimal new). z1 und z2 verweisen auf dasselbe Objekt A (Alias), z3 auf das eigene Objekt B. „A“ und „B“ sind nur Bezeichner für die Skizze; eine Darstellung mit Pfeilen von den Variablen zu den Karten ist gleichwertig.

Erwartungshorizont zu Aufgabe c)

alt ist eine Variable vom primitiven Typ int; sie speichert den Wert 4200 selbst. int neu = alt; kopiert diesen Wert, danach sind alt und neu unabhängig – die Änderung von neu lässt alt unverändert.

z1 ist eine Variable vom Objekttyp Zaehler; sie speichert nur eine Referenz auf das Objekt. Zaehler z2 = z1; kopiert diese Referenz, es entsteht kein neues Objekt. Beide Variablen verweisen auf dasselbe Objekt, daher wirkt z2.erhoehen(150) auf den Zähler, den auch z1 bezeichnet. Für eine unabhängige Kopie wäre ein neues Objekt mit new nötig, wie bei z3.

2

Doppelte Termine im Schulkalender

AFB II–III

Die Schülervertretung entwickelt einen digitalen Schulkalender. Ein Termin besteht aus einem Titel, dem Tag im Schuljahr (1 bis 200) und der Anfangsstunde. Die Klasse Kalender stellt Hilfsmethoden bereit, die Termine als Parameter erhalten. Die Titel werden später aus einer Datei eingelesen; zwei gleich lautende Titel sind dann in der Regel zwei verschiedene String-Objekte. Im Testprogramm wird dieser Fall mit new String("Elternabend") nachgebildet.

Beim Testen fällt auf, dass die Methode istDoppelt einen doppelt eingetragenen Elternabend nicht erkennt. Außerdem ist unklar, ob absagen einen Termin tatsächlich löscht.

Material 2: Klassen Termin und Kalender, Testprogramm
Termin
  • - titel: Zeichenkette
  • - tag: Ganzzahl
  • - stunde: Ganzzahl
  • c Termin(titel: Zeichenkette, tag: Ganzzahl, stunde: Ganzzahl)
  • + getTitel(): Zeichenkette
  • + getTag(): Ganzzahl
  • + getStunde(): Ganzzahl
  • + verschieben(tage: Ganzzahl)
public class Kalender {

    public void verlegen(Termin t, int tage) {
        t.verschieben(tage);
    }

    public void verlegenTag(int tag, int tage) {
        tag = tag + tage;
    }

    public void absagen(Termin t) {
        t = null;
    }

    public boolean kollidiert(Termin a, Termin b) {
        return a.getTag() == b.getTag() && a.getStunde() == b.getStunde();
    }

    public boolean istDoppelt(Termin a, Termin b) {
        return a.getTitel() == b.getTitel() && kollidiert(a, b);
    }
}
Kalender k = new Kalender();
Termin a = new Termin(new String("Elternabend"), 40, 19);
Termin b = new Termin(new String("Elternabend"), 40, 19);
Termin c = a;
System.out.println(k.istDoppelt(a, b));                          // (1)
System.out.println(k.istDoppelt(a, c));                          // (2)
int tag = a.getTag();
k.verlegenTag(tag, 7);
k.verlegen(c, 2);
k.absagen(b);
System.out.println(tag + " " + a.getTag() + " " + b.getTag());  // (3)
System.out.println(k.kollidiert(a, b));                          // (4)
verschieben(tage) addiert tage zum Attribut tag.
  1. Analysieren Sie das Testprogramm, indem Sie die Ausgaben (1) bis (4) ermitteln und jeweils mit der Art der Parameterübergabe bzw. des Vergleichs begründen.
  2. Überprüfen Sie die Aussage einer Mitschülerin: „Die Methode absagen setzt den Termin auf null. Ein anschließender Aufruf b.getTag() führt deshalb zu einem Fehler.“
  3. Implementieren Sie eine korrigierte Methode istDoppelt, die auch für null-Parameter false liefert, sowie eine Methode wiederholen(t: Termin, tage: Ganzzahl): Termin, die einen neuen Termin mit gleichem Titel und gleicher Stunde liefert, der tage Tage später liegt. Der übergebene Termin darf dabei nicht verändert werden.
  4. Beurteilen Sie, ob zum Verlegen eines Termins die vorhandene Methode verlegen (verändert das übergebene Objekt) oder ein Vorgehen wie bei wiederholen (liefert ein neues Objekt) günstiger ist, wenn derselbe Termin gleichzeitig im Kalender der Klasse 11a und im Kalender der Lehrkraft eingetragen ist.

Hinweise

Hinweis zu Aufgabe a)
Zeichne dir zuerst auf, wie viele Termin-Objekte und wie viele String-Objekte es gibt. Unterscheide dann bei jeder Methode: Wird ein int-Wert übergeben oder eine Referenz?
Hinweis zu Aufgabe b)
Der Parameter t ist eine eigene lokale Variable der Methode. Welche Variable wird durch t = null; verändert – und welche nicht?
Hinweis zu Aufgabe c)
Zeichenketten vergleichst du inhaltlich mit equals. Prüfe null, bevor du eine Methode aufrufst. Für ein unabhängiges Objekt brauchst du new.
Hinweis zu Aufgabe d)
Kriterien: Sehen alle Stellen, die den Termin kennen, die Änderung? Was ist gewollt, was unerwünschter Nebeneffekt? Wie viele Objekte entstehen?

Erwartungshorizont

Erwartungshorizont zu Aufgabe a)

(1) false: a und b sind zwei Objekte mit zwei verschiedenen String-Objekten „Elternabend“. == vergleicht bei Zeichenketten die Referenzen, nicht den Inhalt – der erste Teil der Bedingung ist falsch.

(2) true: c verweist auf dasselbe Objekt wie a; beide liefern dieselbe String-Referenz, Tag und Stunde stimmen überein.

(3) 40 42 40: verlegenTag erhält eine Kopie des Wertes 40; die Änderung des Parameters wirkt nicht auf die Variable tag. verlegen(c, 2) erhält eine Kopie der Referenz auf das Objekt, das auch a bezeichnet; verschieben ändert dieses Objekt, daher liefert a.getTag() 42. absagen(b) setzt nur den Parameter auf null, b verweist weiter auf seinen Termin mit Tag 40.

(4) false: Tag 42 und Tag 40 stimmen nicht überein.

Erwartungshorizont zu Aufgabe b)

Die Aussage ist falsch. Beim Aufruf k.absagen(b) wird die Referenz aus b in den Parameter t kopiert. t = null; ändert nur diese lokale Kopie; die Variable b im Testprogramm verweist weiterhin auf das Termin-Objekt. b.getTag() liefert daher 40, wie Ausgabe (3) bestätigt. Auch das Objekt selbst wird nicht verändert. Eine Methode kann über einen Parameter zwar den Zustand des Objekts ändern (wie verlegen), aber nicht, worauf die Variable des Aufrufers verweist.

Erwartungshorizont zu Aufgabe c)
public boolean istDoppelt(Termin a, Termin b) {
    if (a == null || b == null) {
        return false;
    }
    return a.getTitel().equals(b.getTitel()) && kollidiert(a, b);
}

public Termin wiederholen(Termin t, int tage) {
    if (t == null) {
        return null;
    }
    return new Termin(t.getTitel(), t.getTag() + tage, t.getStunde());
}

Wesentlich: equals statt ==; null-Prüfung vor dem ersten Methodenaufruf (Kurzschlussauswertung von ||); in wiederholen ein neues Objekt mit new, ohne t.verschieben aufzurufen. Beispiel: k.wiederholen(a, 7) liefert einen Termin mit Tag 49, a behält Tag 42. Die Rückgabe von null bei fehlendem Termin ist eine sinnvolle, aber nicht zwingende Festlegung.

Erwartungshorizont zu Aufgabe d)

Kriterien: Konsistenz der Daten an allen Stellen, an denen der Termin bekannt ist; Vermeidung unerwünschter Nebeneffekte; Aufwand und Speicherbedarf.

Veränderndes Verlegen: Verweisen beide Kalender auf dasselbe Termin-Objekt (Alias), sieht nach verlegen sofort jeder Kalender den neuen Tag. Die Daten bleiben ohne Zusatzaufwand konsistent, und es entsteht kein weiteres Objekt. Nachteil: Wer den Termin nur „für sich“ verschieben will, verändert unbemerkt auch die anderen Kalender.

Neues Objekt: Der alte Termin bleibt unverändert, es gibt keine Nebeneffekte. Dafür müssten alle Kalender einzeln die alte Referenz durch die neue ersetzen; wird einer vergessen, stehen dort widersprüchliche Termine.

Mögliches Urteil: Für einen gemeinsamen Termin (Klasse und Lehrkraft sollen denselben Zeitpunkt haben) ist das verändernde verlegen günstiger, weil die Alias-Wirkung hier genau erwünscht ist. Das Erzeugen eines neuen Objekts passt dagegen für Wiederholungstermine, bei denen das Original erhalten bleiben muss. Ein anderes Urteil ist bei schlüssiger Begründung ebenfalls möglich.