Autor: HM_JDSZielgruppe: Sek I

Klassen und Objekte

Dieses Kapitel uebertraegt den Inhalt des Arbeitsblatts "Klassen und Objekte" in Buchform. Kernidee: Objektorientierung bedeutet Modellierung. Wir bilden reale oder fachliche Gegenstaende nicht vollstaendig nach, sondern nur die Aspekte, die fuer das Programm relevant sind.

Von der Realitaet zum Modell

Im Arbeitsblatt wird betont: Ein Programmobjekt ist nie die Realitaet selbst, sondern ein Modell.

Beispiel "Konto":

  • In der realen Welt gibt es sehr viele Eigenschaften (IBAN, Inhaber, Buchungshistorie, Limits, Waehrung, Sicherheitsregeln).
  • In einem Einstiegsprojekt nehmen wir vielleicht nur einen Kontostand und zwei Operationen.

Diese Reduktion ist kein Fehler, sondern professionelles Design:

  • nur notwendige Informationen modellieren
  • Komplexitaet kontrollieren
  • spaeter gezielt erweitern

Klasse, Objekt, Attribut, Methode

Die Grundbegriffe aus dem Arbeitsblatt:

  • Klasse: Bauplan
  • Objekt: konkrete Instanz einer Klasse
  • Attribut: gespeicherter Zustand
  • Methode: Verhalten eines Objekts

Eine Klasse allein erzeugt noch kein "lebendiges" Objekt. Erst durch Instanziierung mit new entsteht ein konkretes Exemplar im Speicher.

Beispiel aus dem Blatt: Klasse Konto

public class Konto {
    int kontostand;

    void erhoehen() {
        kontostand = kontostand + 1;
    }

    void verringern() {
        kontostand = kontostand - 1;
    }
}

An diesem Beispiel lassen sich drei Kernpunkte sauber erklaeren:

  1. kontostand ist ein Attribut (Zustand).
  2. erhoehen und verringern sind Methoden (Verhalten).
  3. = ist eine Zuweisung: rechter Ausdruck wird berechnet, dann links gespeichert.

Warum eine Klasse allein nicht reicht

Das Arbeitsblatt weist explizit darauf hin: Eine Klasse ist nur eine Beschreibung. Solange kein Objekt erzeugt wird, existiert noch kein konkretes Konto mit eigenem Zustand.

Konto k1 = new Konto();
Konto k2 = new Konto();

Jetzt gibt es zwei voneinander unabhaengige Objekte.

  • Beide haben dieselben Methoden.
  • Beide haben dieselbe Struktur.
  • Aber jedes Objekt hat seinen eigenen kontostand.

Genau das ist einer der wichtigsten OOP-Gedanken: gemeinsamer Bauplan, individueller Zustand pro Instanz.

Objektzustaende sauber beobachten

Ein typischer Einsteigerfehler ist die Verwechslung von Klassenebene und Objektebene. Deshalb lohnt es sich, den Zustand schrittweise zu notieren:

  1. k1 erzeugen: k1.kontostand == 0
  2. k2 erzeugen: k2.kontostand == 0
  3. k1.erhoehen() dreimal: k1.kontostand == 3, k2.kontostand == 0
  4. k2.verringern() einmal: k1.kontostand == 3, k2.kontostand == -1

Schon dieses kleine Beispiel zeigt, warum OOP fuer modellierende Aufgaben praktisch ist.

Fachsprache aus dem Arbeitsblatt

Das Blatt fuehrt bewusst die Terminologie ein:

  • Variablen innerhalb einer Klasse nennt man in OOP oft Attribute.
  • Befehle/Funktionen innerhalb einer Klasse nennt man Methoden.

Diese Sprache ist nicht nur Theorie. Sie hilft dabei, in Teams praezise zu kommunizieren:

  • "Wir brauchen ein neues Attribut fuer ..."
  • "Diese Methode sollte nicht in diese Klasse, sondern in ..."

BlueJ-Arbeitsweise fuer den Einstieg

Die Aufgabenstellung ist klar: Klasse anlegen, Objekt erzeugen, Methoden aufrufen, Zustand beobachten. Das ist didaktisch sinnvoll, weil der Schritt von "Code schreiben" zu "Objektmodell verstehen" sichtbar wird.

Empfohlene Reihenfolge:

  1. Klasse Konto in BlueJ erstellen.
  2. Objekt k1 erzeugen.
  3. Mehrfach erhoehen() aufrufen.
  4. Methode standAusgeben() ergaenzen.
  5. Zweites Objekt k2 erzeugen und vergleichen.

Erweiterung des Kontobeispiels

Um vom reinen Demo-Code zu einer robusteren Klasse zu kommen, kann das Beispiel schrittweise verbessert werden:

public class Konto {
    private int kontostand;

    public void einzahlen(int betrag) {
        if (betrag > 0) {
            kontostand += betrag;
        }
    }

    public void abheben(int betrag) {
        if (betrag > 0 && betrag <= kontostand) {
            kontostand -= betrag;
        }
    }

    public int getKontostand() {
        return kontostand;
    }
}

Damit werden direkt wichtige OOP-Prinzipien vorbereitet:

  • Kapselung (private)
  • gueltige Zustaende sichern (kein negatives Einzahlen)
  • gezielte Zugriffsmethoden

Typische Fehlerbilder in diesem Kapitel

  1. Methode ohne Objekt aufrufenKonto.erhoehen() statt k1.erhoehen() (bei nicht-statischen Methoden).
  2. Klasse und Objekt verwechseln "Ich habe doch die Klasse geschrieben, warum passiert nichts?" -> weil noch kein Objekt erzeugt wurde.
  3. Zuweisung und Vergleich verwechseln= statt == in Bedingungen.
  4. Objektzustand nicht beobachten Ohne Ausgaben oder Debugging bleibt unklar, wie sich Attribute aendern.

Reflexionsfragen

  1. Welche Eigenschaften waeren fuer ein realistisches Konto zusaetzlich noetig?
  2. Welche Methoden gehoeren in die Klasse Konto und welche nicht?
  3. Wie kann man verhindern, dass ein Objekt in einen ungueltigen Zustand geraet?
  4. Warum ist es sinnvoll, den Kontostand nicht direkt oeffentlich zu machen?

Uebungsaufgaben (ausgebaut)

  1. Erstelle die Klasse Konto wie im Arbeitsblatt.
  2. Ergaenze eine Methode standAusgeben().
  3. Ergaenze einzahlen(int betrag) und abheben(int betrag) mit Gueltigkeitspruefung.
  4. Lege zwei Konto-Objekte an und dokumentiere deren Zustaende nach jedem Methodenaufruf.
  5. Diskutiere, ob ein Konto einen negativen Kontostand haben darf und wie sich das im Code abbilden laesst.

Zusammenfassung

Die zentrale Aussage des Arbeitsblatts bleibt auch in der Buchfassung bestehen:

  • Objektorientierung beginnt mit Modellierung.
  • Klassen sind Bauplaene, Objekte sind konkrete Instanzen.
  • Attribute speichern Zustand, Methoden steuern Verhalten.

Wenn dieser Schritt sicher beherrscht wird, lassen sich in den folgenden Kapiteln Datentypen, Parameter, Kapselung, Konstruktoren und Vererbung auf einer stabilen Grundlage aufbauen.

Abbildungen

In der zugeordneten Datei wurden keine eingebetteten Bildobjekte gefunden.

Modellierungsleitfaden fuer erste Klassen

Beim Uebergang von Alltagssprache zu Quelltext helfen vier Leitfragen:

  1. Welche Dinge sollen im Programm als eigene Objekte auftauchen?
  2. Welche Eigenschaften muessen dauerhaft gespeichert werden?
  3. Welche Aktionen sollen Objekte selbst ausfuehren koennen?
  4. Welche Daten gehoeren nicht in diese Klasse?

Beispielkonto:

  • gehoert hinein: kontostand, einzahlen, abheben
  • gehoert nicht hinein: Dateispeicherung, GUI-Logik, Netzwerkanfragen

So entsteht frueh eine saubere Trennung von Verantwortlichkeiten.

Objektidentitaet und Zustand

Ein oft unterschaetzter Punkt aus den ersten Uebungen: Zwei Objekte mit gleichen Attributwerten sind trotzdem zwei verschiedene Instanzen.

Konto a = new Konto();
Konto b = new Konto();

Auch wenn beide Kontostaende gleich sind, bleiben es zwei Objektidentitaeten. Das ist fuer spaetere Themen wie equals, Sammlungen und Referenzverhalten wichtig.

Vom Rohbeispiel zur stabilen Klasse

Das Arbeitsblatt startet bewusst einfach. Fuer Buchlaenge und spaetere Projekte lohnt sich ein geplanter Ausbau in Stufen.

Stufe 1: reine Demonstration

  • Attribut oeffentlich oder package-sichtbar
  • einfache Inkrement-/Dekrementmethoden

Stufe 2: Kapselung

  • Attribut private
  • Setter/Getter oder fachliche Methoden

Stufe 3: Fachregeln

  • Einzahlen nur bei positivem Betrag
  • Abheben nur bei ausreichendem Kontostand

Stufe 4: Testbarkeit

  • reproduzierbare Testfaelle
  • klare Ausgabe oder Assertions

Diese Stufen bilden eine gute didaktische Progression vom Einstieg zur robusten Implementierung.

Methoden als fachliche Sprache

Methodennamen sollten ausdruecken, was fachlich passiert. Vergleiche:

  • m1() vs. einzahlen(int betrag)
  • foo() vs. druckeKontostand()

Wenn man Klassen spaeter in Teams nutzt, ist diese Lesbarkeit oft wichtiger als eine kurze Schreibweise.

Datenkonsistenz schon im Anfangskapitel

Auch in einem einfachen Konto kann man gueltige und ungueltige Zustaende unterscheiden.

Gueltig:

  • kontostand >= 0 (wenn kein Dispo modelliert wird)

Ungueltig:

  • negative Einzahlung
  • Abhebung ueber den Kontostand

Solche Regeln sollten nicht im aufrufenden Code "irgendwie" beachtet werden, sondern in der Klasse selbst abgesichert sein.

Erweiterungsbeispiel mit Rueckmeldung

public class Konto {
    private int kontostand;

    public boolean einzahlen(int betrag) {
        if (betrag <= 0) {
            return false;
        }
        kontostand += betrag;
        return true;
    }

    public boolean abheben(int betrag) {
        if (betrag <= 0 || betrag > kontostand) {
            return false;
        }
        kontostand -= betrag;
        return true;
    }

    public int getKontostand() {
        return kontostand;
    }
}

Hier liefern Methoden ein boolean, damit Aufrufer direkt sehen, ob die Aktion erfolgreich war.

Objektinteraktion frueh mitdenken

Viele Anfangsbeispiele arbeiten nur mit einem Objekt. Fuer ein realistischeres Verstaendnis sollte frueh Interaktion geuebt werden:

  • Ueberweisung zwischen zwei Konten
  • Vergleich von Kontostaenden
  • Sammelklasse mit mehreren Konten

Beispiel fuer Interaktion:

public static boolean ueberweise(Konto von, Konto nach, int betrag) {
    if (von.abheben(betrag)) {
        return nach.einzahlen(betrag);
    }
    return false;
}

Damit wird sichtbar: Objektorientierung ist nicht nur "eine Klasse", sondern Zusammenarbeit mehrerer Objekte.

Debugging-Muster fuer Einsteiger

Wenn Methodenaufrufe nicht den erwarteten Zustand erzeugen, hilft ein fester Ablauf:

  1. Vorherwert ausgeben
  2. Methode aufrufen
  3. Nachherwert ausgeben
  4. Eingabeparameter protokollieren

Beispiel:

System.out.println("Vorher: " + k.getKontostand());
k.einzahlen(20);
System.out.println("Nachher: " + k.getKontostand());

So wird schnell erkennbar, ob die Ursache im Aufruf oder in der Methode liegt.

Uebungsserie mit steigendem Anspruch

  1. Klasse Konto wie im Arbeitsblatt implementieren.
  2. Methode standAusgeben hinzufuegen.
  3. einzahlen(int) und abheben(int) mit Pruefungen schreiben.
  4. Methode ueberweiseZu(Konto ziel, int betrag) ergaenzen.
  5. Klasse Kunde modellieren, die mehrere Konten verwaltet.

Didaktischer Effekt:

  • von einfacher Klasse
  • ueber Zustandslogik
  • hin zu Beziehungen zwischen Objekten

Reflexionsfragen fuer den Kurs

  1. Wann ist eine Klasse zu gross geworden?
  2. Welche Methode sollte besser in eine andere Klasse verschoben werden?
  3. Welche Attribute sollten niemals direkt von aussen setzbar sein?
  4. Wie laesst sich ein Objektzustand reproduzierbar testen?
  5. Welche Rolle spielt Kapselung fuer spaetere Wartung?

Mini-Projektvorschlag

Entwickle ein "Bibliothekskonto" statt Bankkonto:

  • Attribut: Anzahl ausgeliehener Medien
  • Methoden: ausleihen, zurueckgeben, istLimitErreicht
  • Regel: nicht unter 0, nicht ueber Limit

Damit werden dieselben OOP-Grundideen in einem anderen Kontext geuebt. Der Transfer zeigt, ob die Konzepte wirklich verstanden wurden.

Kapitelkern in einem Satz

Klassen und Objekte sind der Punkt, an dem aus statischem Quelltext ein lebendes Modell wird: Ein gemeinsamer Bauplan erzeugt viele Instanzen mit eigenem Zustand und gemeinsamem Verhalten.

Abschlussaufgabe zu Klassen und Objekten

Implementiere eine Klasse Produkt mit den Attributen name, preisCent, bestand und den Methoden einlagern, verkaufen, istVerfuegbar.

Anforderungen:

  1. Bestand darf nie negativ werden.
  2. Preis muss positiv sein.
  3. Verkauf soll nur bei ausreichendem Bestand erfolgreich sein.
  4. Eine Methode druckeStatus() gibt den aktuellen Zustand lesbar aus.

Reflexion:

  • Welche Felder mussten kapselnd geschuetzt werden?
  • Welche Methoden repraesentieren echtes Verhalten statt reiner Feldmanipulation?

Damit wird das Konto-Beispiel in einen neuen Kontext uebertragen und die OOP-Grundidee stabil verankert.

Pruefungsnahe Kurzfragen

  1. Erklaere den Unterschied zwischen Klasse und Objekt an einem eigenen Beispiel.
  2. Begruende, warum zwei Objekte derselben Klasse unterschiedliche Zustaende haben koennen.
  3. Nenne zwei Gruende, warum Attribute nicht oeffentlich sein sollten.
  4. Zeige an einem Mini-Codebeispiel den Unterschied zwischen Methodenaufruf und Objektinstanziierung.

Diese Fragen eignen sich als schnelle Lernkontrolle am Kapitelende.