Aufgabe 1: Quizzes
Bearbeiten Sie zunächst die Quizzes zu Kapitel 51 und 52 in B. Kjells Java-Buch.
Mit diesem Übungsblatt werden wir das Vererbungskonzept weiter vertiefen und das Prinzip der Polymorphie erarbeiten. Wir nutzen in den folgenden Aufgaben extensiv das Upcasting, welches es erlaubt, einer Referenzvariable der Oberklasse Instanzen ihrer Unterklassen zuzuweisen. Hinsichtlich der Polymorphie sind die Unterklassen bei der Typprüfung kompatibel zur Oberklasse.
Bearbeiten Sie zunächst die Quizzes zu Kapitel 51 und 52 in B. Kjells Java-Buch.
Die Affenforscherin "Besine Gadegas"
wandert durch den Dschungel am Fluss Okongo,
um das Verhalten unterschiedlicher Affenarten zu erforschen. Immer,
wenn sie den Schimpansen "Tschita"
oder den Gorilla "George"
besucht, kreischt der jeweils besuchte vor Freude und isst danach eine Banane.
Zum Abschluss eines jeden Besuches trommelt
george mit den
Fäusten auf seiner Brust, wohingegen sich tschita in die Bäume hangelt.
Implementieren Sie die Besuchssituation auf der Grundlage Ihrer Lösung zu der
ersten Dschungelaufgabe vom letzten Übungsblatt an Hand einer Klasse
Affenforscherin, die über eine Methode
besucht (Affe a) verfügt, unter Ausnutzung
von Polymorphie. Affenforscherinnen besitzen einen Namen.
Rufen Sie alle Methoden, die Handlungen der Affen betreffen, in der Klasse
Affenforscherin auf. Sie müssen hierfür Affen in
Gorillas bzw. Schimpansen umwandeln können, was mit Hilfe expliziter
Typecasts möglich ist. Ein Typecast
für die Umwandlung einer Referenz a auf einen Affen in eine
Schimpansen-Referenz s wird z. B. wie folgt
notiert: Schimpanse s = (Schimpanse) a;
Schreiben Sie ein Sketch-Hauptprogramm, in dem die
Forscherin besine tschita
und george besucht. Im Hauptprogramm finden keine Textausgaben statt.
Ausgabe des Programms:
Besine besucht den Schimpansen Tschita Tschita kreischt Tschita isst eine Banane Tschita hangelt Besine besucht den Gorilla George George kreischt George isst eine Banane George trommelt
Ändern Sie Ihr Programm Buchladen aus dem
letzten Übungsblatt in der folgenden Weise ab:
Die einzelnen Buchtitel werden jetzt in einem Feld vom Typ Buch
gehalten. Geben Sie die Buchdaten mit Hilfe einer
for-Schleife aus.
Ergänzen Sie ihre for-Schleife in der Weise, dass
jeweils nach der Ausgabe der Buchdaten noch geprüft wird, welcher
Klasse das Buchobjekt angehört. Geben Sie den Namen der Klasse aus,
sodass Sie etwa folgende Ausgabe erhalten:
Autor: R. Descartes, Titel: Meditationen, ISBN: n. v. Klasse: Buch Autor: Johann W. v. Goethe, Titel: Die Leiden des jungen Werther, ISBN: n. v., Genre: Liebesroman Klasse: Roman Autor: H. P. Gumm und M. Sommer, Titel: Einführung in die Informatik, ISBN: 3-486-25635-1, Fachgebiet: Informatik Klasse: Sachbuch Autor: W. Pschyrembel, Titel: Klinisches Wörterbuch, ISBN: 3-11-010881-255, Fachgebiet: Medizin Klasse: Medizinbuch
In dieser Übung werden Sie mit Hilfe der Grafikmethoden von
Processing ein paar Grafikklassen implementieren und deren Instanzen
im Grafikfenster von Processing zur Anzeige bringen. Hierfür
benötigen Sie im Sketch-Hauptprogramm
die setup()-Methode, wie auf der Vorlesungsfolie mit
dem Titel "Grafikoperationen" im Abschnitt über die eingebetteten Klassen demonstriert.
Erzeugen Sie zunächst eine neue Sketch-Datei und implementieren Sie das kleine Beispielprogramm von der Folie mit dem Titel "Grafikoperationen". Führen Sie es aus, um zu prüfen, ob soweit alles funktioniert.
Implementieren Sie dann eine abgewandelte Form des Vererbungsbeispiels
aus der Vorlesung
bestehend aus der Oberklasse Shape mit den Unterklassen
Triangle, Square und
Pentagon.

Die Grafikmethoden von Processing funktionieren nur in
Sketch-Dateien. Da wir in den Klassen zu diesen Grafikobjekten die
Grafikmethoden von Processing benötigen, werden diese darum als innere
Klassen in der Sketch-Datei programmiert, wie auf der Folie mit der
Überschrift "Sketch-Datei mit innerer Klasse: Beispiel" demonstriert. D.
h., es werden keine
zusätzlichen Java-Dateien benötigt. Der gesamte Programmcode steht
in der Sketch-Datei.
Die Klasse Shape soll die folgenden Methoden zur Verfügung
stellen:
Shape(float psize): Ein Konstruktor für das Setzen
der Kantenlänge size der jeweiligen Figur gemäß Abb
2. Größen- und Koordinatenangaben werden unter Processing mit dem
Datentyp float codiert.
void draw(float x, float y):
Eine Methode für das Zeichnen der Figur.
Für die allgemeine Figur
Shape besitzt diese Routine einen leeren
Methodenrumpf, da Shape für keine bestimmte
geometrische Figur steht.
In den Konstruktoren der Unterklassen wird der Konstruktor der Oberklasse
verwendet. Die Methode draw(...) der Oberklasse wird
in den Unterklassen überladen. Zu diesem Zweck besitzen die
draw(...)-Methoden der Unterklassen einen
Methodenrumpf
mit dem Code für das Zeichnen der jeweiligen geometrischen Figur
an der Position (x, y). Die
Koordinaten der Kurvenpunkte können Abb. 2 unten entnommen werden.

Erzeugen Sie in Ihrem Hauptprogramm von jedem dieser
Grafikobjekte eines und speichern Sie diese unter Ausnutzung
der Polymorphie in einem Feld des
Typs Shape. Bringen Sie dann die drei
Grafikobjekte mit Hilfe einer Schleife untereinander im
Grafikfenster zur Darstellung, sodass Sie folgendes Ergebnis
erhalten:

Bis jetzt wurde die Methode draw(...) in der Klasse
Shape
mit leerem Methodenrumpf implementiert. Der Nachteil dieser
Herangehensweise ist, dass mit ihrer Hilfe zwar eine Schnittstellenfunktion
definiert, aber das Überladen der Methode in den entsprechenden
Unterklassen
nicht erzwungen wird. Verbessern Sie dies, indem Sie die
Methode als abstrakte Methode deklarieren. Wenn Sie das Programm danach neu starten, sollte
alles so funktionieren wie zuvor. Kommentieren Sie jetzt in einer Klasse,
z. B. Triangle, die Definition der
draw(...)-Methode aus und betrachten Sie die Reaktion der Entwicklungsumgebung im Editor. Was passiert? Warum?
In der abstrakten Klasse Shape treten Schnittstelleneigenschaften
zusammen mit einer Klassenvariablen für die Speicherung von
Parameterwerten auf. Interfaces ermöglichen die reine Definition von
Schnittstellen und sind immer dann sinnvoll, wenn es gilt, dass
Verhalten einer Klasse festzulegen.
Erweitern Sie ihren Klassenbaum um ein als Wurzel des Baums
eingefügtes Interface IShape. Dieses deklariert die
Methode draw(...). Implementieren Sie dieses Interface
mit Hilfe der weiterhin abstrakten Klasse Shape.
Implementieren Sie eine erweiterte Form des generischen
Containers aus der Vorlesung mit dem Namen Punkt, der nicht nur einen Datenwert,
sondern drei Datenwerte speichern kann. Z. B. die x-, y- und z-Koordinate eines Punktes im Raum.
Entsprechend müssen Sie den Konstruktor und
die set-Methode mit mehr Parametern versehen sowie
für jeden Parameter eine eigene get()-Methode implementieren (getX(), getY(), getZ()).
Testen Sie Ihre Implementierung mit jeweils drei Integer- und Float-Punkten sowie mit drei instanzierten LightBulb-Objekten.
Diese werden zunächst jeweils in einem eigenen, an den jeweiligen
Datentyp angepassten Container gespeichert und dann die in dem
jeweiligen Container gespeicherten Daten mittels der get()-Methoden ausgelesen und auf die Konsole ausgegeben. Bei den
Integer- und Float-Punkten sind dies die betreffenden Zahlenwerte, bei
den Glühbirnen ihr Schaltzustand (ein- oder ausgeschaltet).
Kapitel 51: "Abstract Classes and Polymorphism", Kapitel 52: "More about Polymorphism" und Kapitel 53: "Interfaces".
(Druckversion der Kapitel 50-54)