====== Objektbeziehungen ======
Oft bestehen Objekte aus anderen Objekten, z.B. besteht eine Geist-Figur aus einem Bild für den Körper und einem für die Augen:
{{ :objektbeziehungen:pasted:20230110-090504.png }}
Wir realisieren dies im Programm, indem wir entsprechende Attribute ''body'' und ''eyes'' der Klasse ''Sprite'' in der Klasse ''Ghost'' deklarieren und ihnen im Konstruktor entsprechende Objekte zuweisen:
class Ghost {
private Sprite body;
private Sprite eyes;
Ghost(double x, double y) {
body = new Sprite(x, y, SpriteLibrary.PMan, 15);
eyes = new Sprite(x, y, SpriteLibrary.PMan, 19);
}
Die Attribute ''body'' und ''eyes'' nennt man **Objektreferenzen**. Genaugenommen werden innerhalb des ''ghost''-Objekts nämlich nicht die beiden anderen Objekte gespeichert, sondern nur die Adressen, unter denen diese Objekte im Arbeitsspeicher abgelegt sind. \\ \\
Instanzieren wir ein neues ''Ghost''-Objekt mit ''Ghost g = new Ghost(400, 300)'', so sieht das im Objektdiagramm so aus:
{{ :objektbeziehungen:pasted:20230110-092218.png?300 }}
Im Klassendiagramm stellen wir so eine Objektbeziehung folgendermaßen dar:
{{ :objektbeziehungen:pasted:20230110-154251.png?400 }}
\\ \\
Das Schlüsselwort ''private'' vor den Attributdeklarationen besagt, dass auf diese Attribute nur in Methoden der Klasse ''Ghost'' zugegriffen werden kann. Das hat einen entscheidenden Vorteil: Die Autorin der Klasse ''Ghost'' kann in ihrer Klasse Veränderungen vornehmen (z.B. die Attribute umbenennen oder die Augen durch zwei einzelne Sprites darstellen) und kann trotzdem sicher davon ausgehen, dass alle Programme, die diese Klasse verwenden, weiterhin fehlerfrei laufen. Dieses Vorgehen nennt man **Datenkapselung**.
===== Erstes Projekt: Die Klasse Ghost =====
{{ :objektbeziehungen:pasted:20230110-094508.png}}
Wir wollen eine Klasse ''Ghost'' erstellen, die einen Geist darstellt. Dabei soll es möglich sein, im Konstruktor die Farbe des Geistes festzulegen, durch die Methode ''setDirection(String direction)'' die Richtung seiner Augen und durch die Methode ''setDead(boolean dead)'' den Zustand lebend/tot.
===== Bewegen des Geistes =====
Um den Geist flüssig zu bewegen, müssen wir ihn in genau festgelegten Zeitabständen um jeweils ein kleines bisschen verschieben. Wir müssen daher erreichen, dass eine von uns programmierte Methode in genau festgelegten Zeitabständen immer wieder aufgerufen wird. Die Online-IDE stellt uns dafür die Klasse ''Actor'' zur Verfügung und stellt sicher, dass die Methode ''act'' von Actor-Objekten genau 30-mal je Sekunde aufgerufen wird. Wir le
Die Klasse ''Actor'' besitzt eine Methode ''act'', die 30-mal pro Sekunde aufgerufen wird. Wir modellieren unsere Klasse ''Ghost'' daher als Unterklasse von ''Actor'' und überschreiben die ''act''-Methode.