MINT üben

Objektorientierte Modellierung

Zehn Standardaufgaben zur objektorientierten Modellierung: Diagramme lesen, Zustände verfolgen, Kardinalitäten und Vererbung ablesen.

Dein Fortschritt:
0 / 0 Aufgaben
1

Aufgabenblock — AFB I

Zehn Standardaufgaben quer durch das ganze Kapitel — bunt gemischt statt nach Unterkapiteln sortiert: Klassenkarten und Objektkarten lesen, Zustände nach Methodenaufrufen angeben, Kardinalitäten und Vererbungshierarchien ablesen, Listen und überschriebene Methoden verfolgen. Das sind die sicheren Punkte in jeder Klausur zur Objektorientierung.

A1
Klassenkarte lesen: Song
AFB I

Eine Playlist-App verwendet die folgende Klasse. Entnehmen Sie der Klassenkarte, wie viele Parameter der Konstruktor hat und wie viele der Methoden Anfragen bzw. Aufträge sind.

Song
  • - titel: Zeichenkette
  • - interpret: Zeichenkette
  • - dauerSek: Ganzzahl
  • - favorit: Wahrheitswert
  • c Song(titel: Zeichenkette, interpret: Zeichenkette, dauerSek: Ganzzahl)
  • + getTitel(): Zeichenkette
  • + getDauerSek(): Ganzzahl
  • + istFavorit(): Wahrheitswert
  • + markieren()
  • + setDauerSek(dauerSek: Ganzzahl)
Ansatz: Parameter stehen im Konstruktor in der Klammer, jeweils als name: Typ, durch Kommas getrennt.
Unterscheidung: Eine Anfrage liefert einen Wert zurück — in der Karte steht dann hinter der Klammer ein Rückgabetyp. Ein Auftrag ändert den Zustand und hat keinen Rückgabetyp.
Kontrolle: Der Konstruktor ist weder Anfrage noch Auftrag. Zähle also nur die fünf Zeilen mit +.
Vollständige Lösung

Der Konstruktor c Song(titel, interpret, dauerSek) hat 3 Parameter. favorit wird nicht übergeben, sondern im Konstruktor auf false gesetzt.

Anfragen (3): getTitel(): Zeichenkette, getDauerSek(): Ganzzahl, istFavorit(): Wahrheitswert — sie haben einen Rückgabetyp.
Aufträge (2): markieren() und setDauerSek(dauerSek: Ganzzahl) — kein Rückgabetyp, sie ändern den Zustand.

Beachte: Für interpret gibt es keinen Getter. Das Attribut ist privat und damit von außen weder lesbar noch änderbar — ob das so gewollt ist, müsste man im Entwurf klären.

A2
Kardinalitäten lesen: Onlineshop
AFB I

Ein Onlineshop ist so modelliert:

Kunde
  • - name: Zeichenkette
  • - bestellungen: DynArray<Bestellung>
bestellungen*
Bestellung
  • - datum: Zeichenkette
  • - positionen: DynArray<Position>
positionen1..*
Position
  • - menge: Ganzzahl
  • - artikel: Artikel
artikel1
Artikel
  • - preis: Fließkommazahl

Nennen Sie die gesuchten Anzahlen.

Ansatz: Die Zahl am Linienende sagt, wie viele Objekte ein Objekt am Linienanfang kennt.
Mindestens: 1..* heißt „mindestens eins, nach oben offen“.
Kontrolle: Referenzattribute haben den Typ einer anderen Klasse oder einer Liste davon — zähle die Klassen, von denen ein Pfeil ausgeht.
Vollständige Lösung

Eine Position kennt genau 1 Artikel. Eine Bestellung hat mindestens 1 Position (1..*). Referenzattribute haben Kunde (bestellungen), Bestellung (positionen) und Position (artikel) — also 3 Klassen; Artikel kennt niemanden.

Beachte: Das Diagramm sagt nicht, zu wie vielen Bestellungen ein Kunde-Objekt gehört — Rückrichtungen sind nicht modelliert.

A3
Zustand nach Methodenaufrufen: Kaffeeautomat
AFB I

Die Methode kaffeeZubereiten() verbraucht 14 g Bohnen und erhöht becher um 1 — aber nur, wenn noch mindestens 14 g vorhanden sind. auffuellen(gramm) erhöht den Bohnenvorrat.

Kaffeeautomat k = new Kaffeeautomat(40);
k.kaffeeZubereiten();
k.kaffeeZubereiten();
k.kaffeeZubereiten();
k.auffuellen(30);
k.kaffeeZubereiten();

Geben Sie die Attributwerte des Objekts k nach allen Aufrufen an.

g
Ansatz: Lege eine kleine Tabelle an: Zeile für Zeile den Wert von bohnenGramm und becher fortschreiben.
Stolperstelle: Nach zwei Kaffees sind noch 12 g übrig. Was passiert beim dritten Aufruf, wenn die Bedingung bohnenGramm >= 14 nicht erfüllt ist?
Vollständige Lösung

Die Methode im Quelltext:

public class Kaffeeautomat {
    private int bohnenGramm;
    private int becher;

    public Kaffeeautomat(int bohnenGramm) {
        this.bohnenGramm = bohnenGramm;
        becher = 0;
    }

    public void kaffeeZubereiten() {
        if (bohnenGramm >= 14) {
            bohnenGramm = bohnenGramm - 14;
            becher = becher + 1;
        }
    }

    public void auffuellen(int gramm) {
        bohnenGramm = bohnenGramm + gramm;
    }

    public int getBohnenGramm() {
        return bohnenGramm;
    }

    public int getBecher() {
        return becher;
    }
}

Ablauf: 40 g / 0 → 26 g / 1 → 12 g / 2 → dritter Aufruf: 12 < 14, nichts passiert → auffüllen: 42 g / 2 → 28 g / 3.

k: Kaffeeautomat
  • bohnenGramm = 28
  • becher = 3

Typischer Fehler: 4 Becher und 0 g — dann wurde die Bedingung im dritten Aufruf übersehen.

k: Kaffeeautomat
  • bohnenGramm = 40
  • becher = 0
Objektkarte direkt nach dem Konstruktor