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:
kontostandist ein Attribut (Zustand).erhoehenundverringernsind Methoden (Verhalten).=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:
k1erzeugen:k1.kontostand == 0k2erzeugen:k2.kontostand == 0k1.erhoehen()dreimal:k1.kontostand == 3,k2.kontostand == 0k2.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:
- Klasse
Kontoin BlueJ erstellen. - Objekt
k1erzeugen. - Mehrfach
erhoehen()aufrufen. - Methode
standAusgeben()ergaenzen. - Zweites Objekt
k2erzeugen 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
- Methode ohne Objekt aufrufen
Konto.erhoehen()stattk1.erhoehen()(bei nicht-statischen Methoden). - Klasse und Objekt verwechseln "Ich habe doch die Klasse geschrieben, warum passiert nichts?" -> weil noch kein Objekt erzeugt wurde.
- Zuweisung und Vergleich verwechseln
=statt==in Bedingungen. - Objektzustand nicht beobachten Ohne Ausgaben oder Debugging bleibt unklar, wie sich Attribute aendern.
Reflexionsfragen
- Welche Eigenschaften waeren fuer ein realistisches Konto zusaetzlich noetig?
- Welche Methoden gehoeren in die Klasse
Kontound welche nicht? - Wie kann man verhindern, dass ein Objekt in einen ungueltigen Zustand geraet?
- Warum ist es sinnvoll, den Kontostand nicht direkt oeffentlich zu machen?
Uebungsaufgaben (ausgebaut)
- Erstelle die Klasse
Kontowie im Arbeitsblatt. - Ergaenze eine Methode
standAusgeben(). - Ergaenze
einzahlen(int betrag)undabheben(int betrag)mit Gueltigkeitspruefung. - Lege zwei Konto-Objekte an und dokumentiere deren Zustaende nach jedem Methodenaufruf.
- 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:
- Welche Dinge sollen im Programm als eigene Objekte auftauchen?
- Welche Eigenschaften muessen dauerhaft gespeichert werden?
- Welche Aktionen sollen Objekte selbst ausfuehren koennen?
- 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:
- Vorherwert ausgeben
- Methode aufrufen
- Nachherwert ausgeben
- 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
- Klasse
Kontowie im Arbeitsblatt implementieren. - Methode
standAusgebenhinzufuegen. einzahlen(int)undabheben(int)mit Pruefungen schreiben.- Methode
ueberweiseZu(Konto ziel, int betrag)ergaenzen. - Klasse
Kundemodellieren, die mehrere Konten verwaltet.
Didaktischer Effekt:
- von einfacher Klasse
- ueber Zustandslogik
- hin zu Beziehungen zwischen Objekten
Reflexionsfragen fuer den Kurs
- Wann ist eine Klasse zu gross geworden?
- Welche Methode sollte besser in eine andere Klasse verschoben werden?
- Welche Attribute sollten niemals direkt von aussen setzbar sein?
- Wie laesst sich ein Objektzustand reproduzierbar testen?
- 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:
- Bestand darf nie negativ werden.
- Preis muss positiv sein.
- Verkauf soll nur bei ausreichendem Bestand erfolgreich sein.
- 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
- Erklaere den Unterschied zwischen Klasse und Objekt an einem eigenen Beispiel.
- Begruende, warum zwei Objekte derselben Klasse unterschiedliche Zustaende haben koennen.
- Nenne zwei Gruende, warum Attribute nicht oeffentlich sein sollten.
- Zeige an einem Mini-Codebeispiel den Unterschied zwischen Methodenaufruf und Objektinstanziierung.
Diese Fragen eignen sich als schnelle Lernkontrolle am Kapitelende.
