Klassen und Objekte
Eine Klasse legt fest, welche Attribute und Methoden alle ihre Objekte haben. Ein Objekt ist ein konkretes Exemplar mit eigenen Attributwerten.
Objekt und Klasse
Ein Objekt hat einen Zustand (seine Attributwerte) und ein Verhalten (seine Methoden). Die Klasse ist der Bauplan. Zwei Objekte mit gleichen Werten bleiben trotzdem zwei verschiedene Objekte (Identität).
Klassenkarte
Drei Felder: Name, Attribute, Methoden. Sichtbarkeit - privat, + öffentlich; erst der Name, dann : Typ. Der Konstruktor bekommt ein c.
- - titel: Zeichenkette
- - dauer: Ganzzahl
- c Song(titel: Zeichenkette, dauer: Ganzzahl)
- + getDauer(): Ganzzahl
- + kuerzen(sek: Ganzzahl)
Objektkarte
Momentaufnahme eines Objekts: Kopf name: Klasse unterstrichen, darunter nur Attribute mit aktuellen Werten — keine Datentypen, keine Methoden. Zeichenketten stehen in Anführungszeichen.
- titel = "Hymne"
- dauer = 214
Anfrage und Auftrag
Eine Anfrage liefert einen Wert und hat deshalb einen Rückgabetyp (getX(), istX()). Ein Auftrag ändert den Zustand und hat keinen Rückgabetyp.
+ kuerzen(sek: Ganzzahl)
In Java: int, double, String, boolean, char. Eine Reihung schreibt man als „Reihung von Song“, in Java Song[]; eine dynamische Reihung als DynArray<Song>, in Java ArrayList<Song>. Ein Attribut, das ein anderes Objekt kennt, hat den Klassennamen als Typ: - sender: Radiosender.
Klasse oder Objekt?
„Song“ ist die Klasse, „der Song ‚Hymne‘ mit 214 Sekunden“ ist ein Objekt. Wer in einer Objektkarte Datentypen oder Methoden einträgt, hat in Wahrheit eine Klassenkarte gezeichnet.
Klassen implementieren
Aus der Klassenkarte wird Zeile für Zeile Java — Attribute privat, Zugriff nur über Methoden.
Attribute und Konstruktor
Der Konstruktor heißt wie die Klasse und hat keinen Rückgabetyp, auch nicht void. Er gibt allen Attributen einen Startwert. this.nummer ist das Attribut, nummer allein der Parameter.
public class Zimmer {
private int nummer;
private int betten;
private boolean belegt;
public Zimmer(int nummer, int betten) {
this.nummer = nummer;
this.betten = betten;
belegt = false;
}
}Getter und Setter
Der Getter gibt den Wert mit return zurück. Der Setter prüft, ob der neue Wert gültig ist, und übernimmt ihn nur dann. Ohne Setter ist ein Attribut von außen nur lesbar.
public int getBetten() {
return betten;
}
public void setBetten(int betten) {
if (betten >= 1 && betten <= 4) {
this.betten = betten;
}
}Objekte erzeugen und nutzen
Mit new entsteht ein Objekt, der Konstruktor läuft genau einmal. Methoden ruft man mit Punktnotation an einem Objekt auf.
Zimmer z = new Zimmer(204, 2); z.setBetten(3); int b = z.getBetten(); // 3 z.setBetten(9); // abgelehnt b = z.getBetten(); // weiterhin 3
Wert oder Referenz
Eine int-Variable speichert den Wert selbst, eine Zimmer-Variable nur eine Referenz auf das Objekt. b = a kopiert die Referenz: Beide Namen zeigen auf dasselbe Objekt (Alias).
Zimmer a = new Zimmer(101, 1); Zimmer c = a; // kein neues Objekt c.setBetten(2); int n = a.getBetten(); // 2
- betten: Ganzzahl wird private int betten;, + getBetten(): Ganzzahl wird public int getBetten(), + setBetten(b: Ganzzahl) wird public void setBetten(int b). Ohne Rückgabetyp im Diagramm steht in Java void — nur beim Konstruktor steht gar nichts.
== oder equals?
== prüft bei Objekten, ob zwei Referenzen auf dasselbe Objekt zeigen. Ob zwei Zeichenketten den gleichen Inhalt haben, prüft nur s.equals(t). Bei int, double, boolean und char vergleicht == dagegen direkt die Werte.
Assoziationen umsetzen
Objekte kennen andere Objekte. Richtung und Kardinalität im Klassendiagramm legen fest, welches Attribut entsteht.
Linie lesen
Beschriftet mit dem Rollennamen; die offene Pfeilspitze zeigt auf die gekannte Klasse. Die Zahl am Linienende sagt, wie viele Objekte ein Objekt am Anfang kennt.
- - mitglieder: DynArray<Mitglied>
- - name: Zeichenkette
Kardinalität → Attribut
1: Referenz, im Konstruktor gesetzt. 0..1: Referenz, darf null sein. Feste Obergrenze: Reihung dieser Länge. * oder 1..*: dynamische Reihung.
private Trainer trainer; // 1 private Pass pass; // 0..1 private Spieler[] kader = new Spieler[11]; // 0..11 private ArrayList<Mitglied> mitglieder; // *
DynArray und ArrayList
Die Liste muss im Konstruktor erzeugt werden. Die Operationen heißen in Java anders als im Abitur-Pseudocode.
Beide Richtungen
Kennen sich zwei Objekte gegenseitig, gibt es zwei Attribute. Eine einzige Methode setzt oder löscht beide Referenzen — sonst widersprechen sich die Objekte.
public void zurueckgeben() {
if (ausleiher != null) {
ausleiher.setRad(null);
ausleiher = null;
}
}„genau ein“ → 1, „höchstens ein“ → 0..1, „beliebig viele, auch keine“ → *, „mindestens ein“ → 1..*, „bis zu n“ → 0..n. Die Zahl steht immer bei der Klasse, die gezählt wird.
Referenz statt Name
Eine Beziehung speichert das Objekt selbst (- trainer: Trainer), nicht seinen Namen oder eine Nummer. Nur so ist der Partner eindeutig und seine Methoden sind direkt aufrufbar.
Vererbung und Entwurf
Gemeinsames wandert in eine Oberklasse, Besonderes bleibt unten. Aus einem Anforderungstext wird Schritt für Schritt ein Klassendiagramm.
Ober- und Unterklasse
Linie mit hohlem Dreieck an der Oberklasse. Die Unterklasse erbt alle Attribute und Methoden und nennt im Diagramm nur, was sie ergänzt oder überschreibt. # (protected) ist auch in Unterklassen sichtbar.
- - kennzeichen: Zeichenkette
- + maut(km: Ganzzahl): Ganzzahl
- - sitze: Ganzzahl
- - achsen: Ganzzahl
- + maut(km: Ganzzahl): Ganzzahl
extends, super, @Override
super(…) ist die erste Anweisung im Konstruktor. Eine überschreibende Methode hat denselben Kopf; mit super.maut(km) nutzt sie die Fassung der Oberklasse.
public class LKW extends Fahrzeug {
private double nutzlast;
public LKW(String k, double nutzlast) {
super(k);
this.nutzlast = nutzlast;
}
@Override
public int maut(int km) {
return km * 5 + super.maut(km);
}
}Polymorphie
Eine Variable vom Typ der Oberklasse darf auf ein Unterklassen-Objekt zeigen. Der Compiler prüft nur den Variablentyp; welcher Rumpf läuft, entscheidet zur Laufzeit das Objekt (dynamische Bindung).
Fahrzeug f = new LKW("H-B 2", 7.5);
int m = f.maut(100); // 700: LKW-Methode
f.beladen(3); // Übersetzungsfehler!Vom Text zum Diagramm
Substantive mit eigenen Eigenschaften → Klassen, einfache Werte → Attribute, Verben → Methoden, „hat/kennt“ → Assoziation mit Kardinalität aus den Mengenwörtern, „ist ein“ → Vererbung. Synonyme und das System selbst streichen.
Software im Team
Erst Anforderungen klären, dann das Klassendiagramm als verbindliche Schnittstelle vereinbaren, Klassen aufteilen und implementieren. Testfälle werden vorher festgelegt.
Ein LKW ist ein Fahrzeug, ein Auto hat einen Motor. Gleiche Attribute oder gleicher Schaden allein sind kein Grund für Vererbung — nur der ist-ein-Satz entscheidet.
Was der Compiler sieht
Nach Fahrzeug f = new LKW(…); sind über f nur Methoden von Fahrzeug aufrufbar. Die Zuweisung „nach oben“ geht immer, „nach unten“ (LKW l = f;) nie ohne Typumwandlung.
Die Regeln, an denen die Punkte hängen
Die meisten Punkte gehen in dieser Klausur nicht durch schwere Aufgaben verloren, sondern durch kleine, immer gleiche Ungenauigkeiten.
Regel 1 — Notation exakt
Klassenkarte: Sichtbarkeit, name: Typ, c vor dem Konstruktor, Rückgabetyp nur bei Anfragen. Assoziation mit Rollenname, Pfeilspitze und Kardinalität an der gezählten Klasse; Vererbung mit hohlem Dreieck an der Oberklasse.
Regel 2 — Konstruktoren vollständig
Kein void, jedes Attribut initialisieren, this. bei gleichen Namen, Listen mit new erzeugen und in Unterklassen super(…) als erste Anweisung.
Regel 3 — Referenzen ernst nehmen
Zuweisungen kopieren nur Referenzen. Vor Aufrufen über 0..1-Beziehungen und Reihungsplätze auf null prüfen; Beziehungen in beide Richtungen immer gemeinsam setzen.
Regel 4 — Entwurf begründen
Jede Klasse, jede Kardinalität und jede Vererbung lässt sich auf einen Satz der Anforderungen zurückführen. Wer das in der Begründung zeigt, sichert die Punkte im AFB III.
