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)
Modellieren aus Text
„Ein Aquarium enthält Fische. Jeder Fisch hat eine Art und ein Alter und kann gefüttert werden.“ Substantive mit eigenen Eigenschaften werden Klassen, einfache Werte werden Attribute, Verben werden Methoden.
Verb → Methode
In Java: int, double, String, boolean, char. Eine Reihung schreibt man als „Reihung vom Typ Song“, in Java 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.
Mit Objekten arbeiten
Objekte kennen andere Objekte, nutzen fertige Klassen wie String und werden in Reihungen verwaltet.
Objekte kennen Objekte
Ein Attribut vom Typ einer anderen Klasse stellt die Beziehung her — im Konstruktor oder per Setter. Über die Referenz gibt man Aufträge weiter (Delegation).
Akku a = new Akku(80);
Scooter s = new Scooter("S-17", a);
int l = s.getAkku().getLadung(); // 80Gegebene Klassen nutzen
Aus der Dokumentation reichen Name, Parameter und Rückgabe. Indizes zählen ab 0, substring(a, b) endet vor Index b.
String t = "Hotelzimmer";
int n = t.length(); // 11
char c = t.charAt(0); // 'H'
String s = t.substring(5, 9); // "zimm"
int p = t.indexOf("zimmer"); // 5Reihungen von Objekten
new Kiste[4] erzeugt nur vier leere Plätze mit null — jede Kiste braucht ihr eigenes new. Beim Durchlauf vor jedem Methodenaufruf auf null prüfen.
Kiste[] regal = new Kiste[4];
regal[0] = new Kiste(12);
regal[2] = new Kiste(7);
int summe = 0;
for (int i = 0; i < regal.length; i++) {
if (regal[i] != null) {
summe = summe + regal[i].getGewicht();
}
}
// summe = 19Software im Team
Erst Anforderungen klären, dann das Klassendiagramm als verbindliche Schnittstelle vereinbaren, dann Klassen aufteilen und implementieren. Testfälle werden vorher festgelegt.
- - kennung: Zeichenkette
- - akku: Akku
- c Scooter(kennung: Zeichenkette, akku: Akku)
- + getAkku(): Akku
- - ladung: Ganzzahl
- c Akku(ladung: Ganzzahl)
- + getLadung(): Ganzzahl
Einfache Linie mit Beschriftung und Kardinalitäten, keine Pfeilspitze. Im Quelltext wird daraus private Akku akku;. Ist noch kein Akku zugeordnet, ist die Referenz null — ein Aufruf akku.getLadung() führt dann zur NullPointerException.
Kette von Aufrufen lesen
s.getAkku().getLadung() liest man von links nach rechts: s.getAkku() liefert ein Akku-Objekt, an dem dann getLadung() aufgerufen wird. Jede Stelle in der Kette muss ein Objekt liefern, sonst gibt es eine NullPointerException.
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. Objektkarte: Kopf unterstrichen, nur Werte. Assoziation als einfache beschriftete Linie mit Kardinalitäten.
Regel 2 — Konstruktor, this und Setter
Kein void vor dem Konstruktor, jedes Attribut initialisieren, bei gleichnamigen Parametern this. schreiben. Ein Setter ohne Prüfung verschenkt den Punkt für die Datenkapselung.
Regel 3 — Referenzen ernst nehmen
Jedes Objekt braucht sein eigenes new, eine Zuweisung kopiert nur die Referenz. Vor Aufrufen in Reihungen auf null prüfen, Zeichenketten mit equals vergleichen und bei substring das Ende exklusiv zählen.
