Professional Documents
Culture Documents
• Deutlich flexibler sind die Zeichenprogramme, wie z.B. StarOffice Draw. Derartige Programme
besitzen intern eine Beschreibung für Objekte wie
Linien, Kreise und Rechtecke. Du kannst daher die
Objekte jederzeit erneut auswählen und jede ihrer
Eigenschaften verändern.
Auch beim Vergrößern eines Ausschnittes bleiben alle
Linien glatt und gleichmäßig, da die Darstellung des
Objektes der neuen Auflösung angepasst wird. Da auch
die Druckqualität entsprechend hoch ist, arbeiten alle
Konstruktionsprogramme objektorientiert.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 -2- Hansa-Gymnasium
Für das Zeichnen von Möbeln gibt es genormte Darstellungen, die auch für das vorliegende Projekt
zur Anwendung kommen sollen.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 -3- Hansa-Gymnasium
Einführung
Zur Einführung kannst du dir die Elemente eines Computer-Desktops ansehen: Buttons auf der
Taskleiste, Programmlinks, Dokumente, usw.
Fragestellungen:
• Was seht ihr?
• Welche Gemeinsamkeiten haben die einzelnen Elemente auf dem Desktop?
• Welche Eigenschaften haben diese Elemente?
• Was kann ich mit diesen Elementen machen?
Ergebnisse:
• Es gibt Gruppen gleichartiger Elemente, z.B. Buttons, Dokumente, Programme und Links.
• Die Gruppen werden als Klassen bezeichnet.
• Die einzelnen Elemente sind die Objekte der jeweiligen Klasse.
• Die Elemente bestehen u.a. aus Icon und Namen (Attribute).
• Sie reagieren unterschiedlich (Programme werden gestartet, Dokumente geöffnet), man kann sie
verschieben usw. (Methoden).
Beispiele:
• Körperformen (s. Arbeitsblatt Körperformen)
• Tiere, Pflanzen, Menschen,
• Auto und ein konkretes Auto zur Unterscheidung zwischen Klasse und Exemplar (Instanz).
Genau dies spielt auch im Zusammenhang mit Klassen und Objekten eine Rolle.
Modellbildung
Programmierung ist ein Modellbildungsprozess. Bei allen Modellbildungen betrachtet man einen
Ausschnitt der realen Welt und versucht ihn mit einem formalen System, z.B. einer
Computersprache zu beschreiben.
Wesentlicher Teil des Modellbildungsprozesses ist es diejenigen Objekte zu identifizieren, die auch
im Modell eine Rolle spielen. Im weiteren Verlauf der Modellbildung geht es dann darum die
identifizierten Objekte zu kategorisieren und in Klassen zusammen zu fassen.
Klasse
Klassen fassen Objekte mit gleichen Eigenschaften und gleichem Verhalten zusammen. Schreiben
wir in Java eine Klassendefinition, dann beschreiben wir in ihr, welche Eigenschaften und welches
Verhalten ein Objekt hätte, das dieser Klasse zugehören soll, wenn wir es erzeugen würden.
Objekt
Ein Objekt ist ein konkretes Exemplar, eine Instanz, die zu einer Klasse gehört.
Deutlich werden die Begriffe, wenn man auf alltägliche Beispiele abhebt. Relativ wichtig in
unserem Alltag ist die Klasse Automobil, die bestimmte Fahrzeuge zusammenfasst.
Der alte Bully des Deutschlehrers ist dann ein konkretes Objekt, eine Instanz der Klasse Auto,
genau wie der Mercedes des Physiklehrers ein Objekt darstellt.
Im Zusammenhang mit der Textverarbeitung lassen sich dann Klassen wie Absatz, Zeichen oder
Seite identifizieren. Eine konkrete Instanz der Klasse Absatz und damit ein Objekt der
Textverarbeitung wäre dann der vorliegende Textteil.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 -5- Hansa-Gymnasium
Für die ersten Schritte benötigst du die Menüleiste, in der sich der Punkt Projekt findet. In dem
Projekt-Menü findet du den Unterpunkt Projekt
öffnen... über den du einen Dialog zum Öffnen von
BlueJ-Projekten erhält. Im Verzeichnis Abschnitt 3
der Materialien zu dieser Einführung findet sich u.a.
das BlueJ-Projekt Figuren. Nach dem Laden dieses
Projektes ergibt sich das folgende Bild.
Methoden aufrufen
Um den zugehörigen Kreis auf den Bildschirm zu bekommen klickst
du mit der rechten Maustaste auf das Objekt in der Objektleiste,
worauf sich sein Kontextmenü öffnet.
Hier gibst du eine Zahl ein z.B. 50, worauf der kreis1 sich
um 50 Pixel horizontal verschiebt.
Datentypen in Java
Ein Datentype beschreibt die Art der Information, die Java z.B. als Parameter einer Methode
erwartet. Viele der Methoden von Kreis erwarten Zahlen als Parameter, der zugehörige Datentyp
heißt in Java int, was eine Abkürzung von integer, dem englischen Begriff für ganze Zahl ist.
Die Methode farbeAendern erwartet einen Text, eine Zeichenkette. Der zugehörige Datentyp heißt
in Java String. Strings oder Zeichenketten musst du generell in Anführungsstriche setzen.
Mehrere Instanzen
Bisher hast du nur mit einem einzigen Objekt gearbeitet,
einer Instanz der Klasse Kreis. Du kannst beliebig viele
Instanzen der gleichen Klasse erzeugen, aber auch
Instanzen verschiedener Klassen gleichzeitig. Bei
verschiedenen Instanzen der gleichen Klasse musst du
aber unbedingt darauf achten, dass sie unterschiedliche
Positionen besitzen, sonst kannst du sie im
Leinwandfenster nicht unterscheiden.
Aufgabe 1:
a) Erzeuge mit BlueJ und den Klassen Kreis, Quadrat und
Dreieck interaktiv eine Abbildung, die ein einfaches Haus mit
einer Sonne darstellt.
b) Versuche dabei dir die einzelnen Schritte bzw.
Methodenaufrufe so zu merken, dass du eine erneute
Darstellung des gleichen Bildes möglichst direkt erzeugen
könntest.
c) Falls du genügend Zeit zur Verfügung hast kannst du die
Zeichnung noch um weitere Elemente, wie z.B.
Tannenbäume ergänzen.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 -8- Hansa-Gymnasium
Aufgabe 2
Verändere den Quelltext von Zeichnung so, dass die Sonne nicht mehr gelb, sondern rot ist. Dazu
musst du im Quelltext die Zeile suchen, in der die Farbe der Sonne geändert wird.
Aufgabe 3
a) Erweitere den Quelltext von Zeichnung um ein weiteres Objekt, einen Mond. Der Mond soll
etwas kleiner sein als die Sonne und links vom Dach erscheinen.
b) Die Klasse Zeichnung kennt die Methoden inSchwarzWeissAendern und inFarbeAendern. Achte
darauf, dass diese Methoden auch den Mond beeinflussen.
c) Falls du noch Zeit hast kannst du deine Zeichnung um einen Tannenbaum erweitern, der
unterhalb der Sonne neben dem Haus stehen kann.
Aufgabe 4 (anspruchsvoller)
Der Mond aus Aufgabe 3 soll nach dem Zeichnen langsam untergehen.
a) Die Klasse Kreis stellt die Methoden langsamHorizontalBewegen und langsamVertikalBewegen
zur Verfügung, die du innerhalb von zeichne benutzen kannst.
b) Schreibe eine extra Methode monduntergang, die von der Methode zeichne getrennt ist. Man soll
also mittels zeichne das Bild aufbauen und dann mit monduntergang den Mond untergehen lassen.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 10 - Hansa-Gymnasium
Sowohl Tisch, als auch Stuhl verfügen über eine Methode dreheAuf,
über die die Orientierung der Möbelstücke verändert werden kann.
Der Winkel wird hierbei im Gradmass angegeben.
In der folgenden Aufgabe sollst du eine eigene Klasse erstellen. Dazu sind ein paar Informationen
zu Java-Klassen notwendig. Bei einer Java-Klasse müssen Dateiname und Klassenname
übereinstimmen. Eine Klasse Einrichtung muss also unter dem Dateinamen Einrichtung.java
abgespeichert sein, wobei auch die Gross-/Kleinschreibung wichtig ist. Jede Java-Klasse verfügt
über einen Konstruktor, der dazu dient Voreinstellungen vorzunehmen. Der Konstruktor darf ruhig
leer sein, muss aber so heissen, wie die Klasse.
public Einrichtung()
{
// nichts zu tun hier, alle Exemplarvariablen werden automatisch
// mit null initialisiert
}
Java führt bei leerem Konstruktor automatisch einige Initialisierungen durch. Oftmals wird man
aber im Konstruktor auch eigene Einstellungen vornehmen:
public Tisch()
{
xPosition = 120;
yPosition = 150;
orientierung = 0;
farbe = "rot";
istSichtbar = false;
breite = 120;
tiefe = 100;
}
Einem Konstruktor kann man auch Parameter übergeben, wie einer normalen Methode. Das wird in
einem späteren Abschnitt eine Rolle spielen.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 11 - Hansa-Gymnasium
Aufgabe5
Erstelle mit dem Projekt MoebelAnfang eine kleine
Sitzgruppe, zuerst interaktiv und dann, indem du eine
zusätzliche Klasse Einrichtung einführst, die die
Sitzgruppe darstellt. Du kannst dich bei der Erstellung an
der Klasse Zeichnung aus Abschnitt 3 orientieren.
Für die Verwendung des Begriffes Aggregation ist es wichtig, dass die benutzten Klassen auch
unabhängig von der benutzenden Klasse existenzfähig sind. Falls diese Unabhängigkeit nicht
gegeben ist spricht man von einer Komposition. Ein Tisch hat Tischbeine, diese würde man
normalerweise nicht als vom Tisch unabhängig existenzfähig betrachten. Wenn ich den Tisch
wegwerfe, dann normalerweise auch seine Beine.
Ein weiteres Merkmal der Aggregation ist auch dass das Aggregat auch zeitweise ohne Teile sein
darf, eine Einrichtung ohne Tisch und Stuhl ist denkbar, ein Tisch ohne Beine aber nicht.
Aggregation und Komposition gehören beide zu den Assoziationen. BlueJ stellt Assoziationen
durch Pfeile zwischen den Klassen dar, unterscheidet aber nicht zwischen Aggregation und
Komposition.
Weitere Möbelklassen
Eine Einrichtung, die nur aus Tischen und Stühlen besteht ist relativ langweilig, deshalb soll das
Programm im nächsten Schritt um weitere Möbelklassen erweitert werden.
Aufgabe 6
Schreibe die Möbelklassen Bett, Sofa und Schrankelement, orientiere dich bei der Darstellung an
den Normzeichen für Möbel von Abschnitt 1.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 12 - Hansa-Gymnasium
Grafikbefehle in Java
Die Lösung der Aufgabe 6 ist solange nicht besonders schwierig, wie man bei Objekten bleibt, die
sich aus Linienzügen zeichnen lassen. Die Möbelstücke unterscheiden sich vor allem in der
Methode gibAktuelleFigur(). Für den Stuhl hat die Methode folgenden Inhalt:
return t1.createTransformedShape(stuhl);
}
Zentrale Komponente hier ist GeneralPath, was man als Zeichenanweisung interpretieren kann.
Hier werden quasi die Anweisungen bzw. Arbeitsschritte gespeichert, die man zum Zeichen des
Objektes benötigt. Benutzt werden hier zum Zeichnen die Methoden moveTo() und lineTo(). Die
erste Methode verschiebt die Position des Zeichenstiftes ohne eine Spur zu hinterlassen. Die zweite
Methode hinterlässt eine Spur.
Die letzten drei Zeilen der Methode definieren eine Transformation, konkret eine Drehung der
Zeichnung um ihren Mittelpunkt.
Mit diesen Informationen sollten sich Möbelstücke wie Bett, Schrank und Sofa zeichnen lassen.
Etwas schwieriger wird es, wenn man abgerundete Möbelstücke, wie Klavier oder Badewanne
zeichnen möchte. Hier benötigt man weitere Informationen.
Java ist eine sehr gut dokumentierte Sprache, die Dokumentation wird automatisch aus
Kommentaren im Quelltext erzeugt werden.
Java besteht aus mehreren Paketen, z.B. dem Paket java.awt.geom mit Grafikfunktionen. Klick man
im Frame links oben auf java.awt.geom, so werden im Frame direkt darunter alle Klassen angezeigt.
Klickt man hier z.B. auf die Klasse GeneralPath, so erscheint im großen Frame die zugehörige
Dokumentation mit allen Methoden dieser Klasse.
Hier finden sich dann z.B. auch moveTo() und LineTo() mit relativ abstrakten Beschreibungen.
Recht mächtig sind hier auch die Methoden quadTo() und curveTo(), die die Angabe von zwei bzw.
drei Punkten erwarten. Die Methode quadTo() verbindet den aktuellen Punkt mit dem zweiten
Punkt über eine Kurve, deren Krümmung mit dem ersten angegebenen Punkt bestimmt wird.
Das folgende Listing erzeugt einen Kreisbogen, um den herum ein
Quadrat gezeichnet ist.
private Shape gibAktuelleFigur()
{
GeneralPath Test = new GeneralPath();
Test.moveTo(xPosition , yPosition);
Test.lineTo(xPosition+breite, yPosition);
Test.lineTo(xPosition+breite, yPosition+tiefe);
Test.lineTo(xPosition , yPosition+tiefe);
Test.lineTo(xPosition , yPosition);
return t1.createTransformedShape(Test);
}
Die Methode curveTo() arbeitet entsprechend, nur dass hier mit zwei Hilfspunkten gearbeitet wird,
die die Darstellung von S-förmigen Kurven erlauben.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 14 - Hansa-Gymnasium
Vererbung
Beim Bearbeiten der Aufgabe 6 müsste dir aufgefallen sein, dass du mehrfach gleiche bzw. sehr
ähnliche Codezeilen schreiben musst. Derartige Redundanzen sollte man in der Programmierung
unbedingt vermeiden. Jede deiner Möbelklassen verfügt z.B. über die Methode zeige:
public void zeige()
{
istSichtbar = true;
zeichne();
}
Diese Methode ist vollkommen unabhängig von der konkreten Möbelklasse.
Eine Möglichkeit die Redundanzen zu vermeiden besteht darin eine sehr allgemeine Klasse
Moebelstueck zu definieren, von der die konkreten Möbelstücke dann erben.
import java.awt.Shape;
/**
* Ein allgemeines Möbelstück, als Grundlage für Vererbung.
*
* @author Java-MS Groupies
* hier Uwe Debacher
* nach Vorlagen von Michael Kölling und David J. Barnes und Axel Schmolitzky
* @version 1.1 (23.2.04)
*/
abstract public class Moebelstueck
{
public int xPosition;
public int yPosition;
public int orientierung;
public String farbe;
public boolean istSichtbar;
/**
* Erzeuge ein Moebelstueck mit einer Standardfarbe an einer
* Standardposition.
*/
public Moebelstueck()
{
xPosition = 160;
yPosition = 80;
farbe = "blau";
orientierung = 0;
istSichtbar = false;
}
/**
* Berechnet das zu zeichnende Shape anhand der gegebenen Daten
* [ Zum Anzeigen der Attributwerte über Inspect muss hier die Sichtbarkeit
* auf public gesetzt werden. ]
*/
abstract public Shape gibAktuelleFigur();
/**
* Mache dieses Objekt sichtbar. Wenn es bereits sichtbar ist, tue
* nichts.
*/
public void zeige()
{
istSichtbar = true;
zeichne();
}
/**
* Mache dieses Objekt unsichtbar. Wenn es bereits unsichtbar ist, tue
* nichts.
*/
public void verberge()
{
loesche();
istSichtbar = false;
}
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 15 - Hansa-Gymnasium
/**
* Drehe auf den angegebenen Winkel
*/
public void dreheAuf(int neuerWinkel)
{
loesche();
orientierung = neuerWinkel;
zeichne();
}
/**
* Bewege dieses Objekt horizontal um 'entfernung' Bildschirmpunkte.
*/
public void bewegeHorizontal(int entfernung)
{
loesche();
xPosition += entfernung;
zeichne();
}
/**
* Bewege dieses objekt vertikal um 'entfernung' Bildschirmpunkte.
*/
public void bewegeVertikal(int entfernung)
{
loesche();
yPosition += entfernung;
zeichne();
}
/**
* Ändere die Farbe dieses Objektes in 'neueFarbe'.
* Gültige Angaben sind "rot", "gelb", "blau", "gruen",
* "lila" und "schwarz".
*/
public void aendereFarbe(String neueFarbe)
{
farbe = neueFarbe;
zeichne();
}
/*
* Zeichne dieses Objekt mit seinen aktuellen Werten auf den Bildschirm.
*/
private void zeichne()
{
if (istSichtbar)
{
Shape figur = gibAktuelleFigur();
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.zeichne (
this,
farbe,
figur);
leinwand.warte(10);
}
}
/*
* Lösche dieses Objekt vom Bildschirm.
*/
private void loesche()
{
if (istSichtbar)
{
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.entferne(this);
}
}
}
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 16 - Hansa-Gymnasium
Von dieser Klasse erben dann die konkreten Möbelklassen, was zu deutlich übersichtlicheren
Quelltexten führt.
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.Graphics2D;
/**
* Ein Tisch, der manipuliert werden kann und sich selbst auf einer Leinwand zeichnet.
*
* @author Java-MS Groupies
* hier claus albowski
* nach einer Vorlage von Uwe Debacher,
* Michael Kölling und David J. Barnes und Axel Schmolitzky
* @version 1.1 (8.2.04)
*/
public class Tisch extends Moebelstueck
{
private int xPosition;
private int yPosition;
private int orientierung;
private String farbe;
private boolean istSichtbar;
private int breite;
private int tiefe;
/**
* Erzeuge einen neuen Tisch mit einer Standardfarbe an einer
* Standardposition.
*/
public Tisch()
{
breite = 120;
tiefe = 100;
}
/**
* Berechnet das zu zeichnende Shape anhand der gegebenen Daten
* [ Zum Anzeigen der Attributwerte über Inspect muss hier die Sichtbarkeit
* auf public gesetzt werden. ]
*/
public Shape gibAktuelleFigur()
{
Shape tisch = new Ellipse2D.Double(xPosition , yPosition, breite, tiefe);
return t1.createTransformedShape(tisch);
}
/**
* Hole die X-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteX()
{
return xPosition+breite/2;
}
/**
* Hole die Y-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteY()
{
return yPosition+tiefe/2;
}
}
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 17 - Hansa-Gymnasium
Idealerweise möchte man eine derartige Sammlung zu Laufzeit des Programms erstellen und
erweitern können, was bei dem bisherigen Ansatz nicht möglich ist.
Aufgabe 7
Öffne das Projekt Notizbuch1 aus dem Verzeichnis Abschnitt5. Das Projekt besteht nur aus einer
einzigen Klasse Notizbuch, die einzelne Einträge verwalten kann. Arbeite mit dieser Klasse gib u.a.
mehrere Notizen ein.
Analysiere die Funktionsweise der Sammlung, die Notizbuch benutzt.
import java.util.ArrayList;
/**
* Eine Klasse zur Verwaltung von beliebig langen Notizlisten.
* Notizen sind nummeriert, um durch einen Benutzer referenziert
* werden zu können.
* In dieser Version starten die Notiznummern bei 0.
*
* @author David J. Barnes and Michael Kolling.
* @version 2003.04.15
*/
public class Notizbuch
{
// Speicher für eine beliebige Anzahl an Notizen.
private ArrayList notizen;
/**
* Führe die Initialisierungen durch, die für ein Notizbuch
* notwendig sind.
*/
public Notizbuch()
{
notizen = new ArrayList();
}
/**
* Speichere eine neue Notiz in diesem Notizbuch.
* @param notiz die zu speichernde Notiz.
*/
public void speichereNotiz(String notiz)
{
notizen.add(notiz);
}
/**
* @return die Anzahl der Notizen in diesem Notizbuch.
*/
public int anzahlNotizen()
{
return notizen.size();
}
/**
* Zeige eine Notiz.
* @param notiznummer die Nummer der Notiz, die gezeigt werden soll.
*/
public void zeigeNotiz(int notiznummer)
{
if(notiznummer < 0) {
// Keine gültige Nummer, nichts zu tun.
}
else if(notiznummer < anzahlNotizen()) {
// Die Nummer ist gültig, wir können die Notiz ausgeben.
System.out.println(notizen.get(notiznummer));
}
else {
// Keine gültige Nummer, nichts zu tun.
}
}
}
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 18 - Hansa-Gymnasium
Aufgabe 8
Erweitere das Projekt Notizbuch so, dass einzelne Notizen auch gelöscht werden können, dafür
steht in einer ArrayList die Methode remove(int nummer) zur Verfügung.
Iteration
Will man alle Notizen des Notizbuches ausgeben, so benötigt man eine Wiederholstruktur oder
Schleifenstruktur. Java kennt dafür mehrere Konstrukte, die hier jeweils gleich am konkreten
Beispiel dargestellt werden.
Die while-Schleife
Sehr einfach zu handhaben ist die while-Schleife. Hier wird ein Programmteil solange ausgeführt,
wie eine Bedingung wahr ist.
while (Schleifenbedingung) {
Schleifenrumpf
}
int index = 0;
while(index < notizen.size()) {
System.out.println(notizen.get(index));
index++;
}
Iteratoren
Bei der Ausgabe der Notizen spielen die Nummern der Einträge eigentlich keine grosse Rolle. Es
gibt Sammlungen, bei denen Nummern auch gar nicht vorhanden sind. Da ist ein Konstrukt
übersichtlicher, mit dem man formulieren kann, wenn es einen weiteren Datensatz gibt, dann gib
den nächsten Datensatz aus. Genau so arbeitet ein Iterator.
Jede Sammlung, wie in diesem Fall die ArrayList, verfügt über ein Iterator-Objekt. Dieses Iterator-
Objekt kennt dann die Methoden hasNext() und next().
Iterator it = notiz.iterator();
while(it.hasNext()) {
System.out.printeln(it.next()),
}
Die for-Schleife
Wenn man genau weiss, wie oft eine Iteration durchzuführen ist, dann kann man auch mit der for-
Schleife arbeiten, die schon in einem der ersten Beispiele auftauchte.
Welche der beiden Schleifenarten man bevorzugt hängt von der Situation und auch dem
persönlichen Geschmack ab. Im Zweifelsfall sollte man der while-Schleife den Vorzug geben.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 19 - Hansa-Gymnasium
Ein Hinweis noch zum Umgang noch mit der Konsole von BlueJ. Ausgaben wie
System.out.printeln(it.next())
erfolgen auf die Systemkonsole des jeweiligen Betriebssystems. Bei Windos ist das üblicherweise
ein schwarzes Fenster das zur DOS-Shell gehört. BlueJ
fängt diese Ausgaben ab und leitet sie in ein Fenster seiner
grafischen Oberfläche um.
Dieses Fenster benimmt sich aber ähnlich wie das DOS-
Fenster, es sammeln sich vor allem die Ausgaben
unterschiedlicher Programmdurchläufe an, was schnell
unübersichtlich wird. Daher bietet BlueJ für dieses Fenster
auch eine Löschfunktion an.
Über Optionen -> Konsole löschen steht diese Funktion
jederzeit zur Verfügung.
Aufgabe 9
Erweitere das Projekt Notizbuch um eine Methode zum Anzeigen aller Einträge.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 20 - Hansa-Gymnasium
6. Polymorphie
Die Aufgabe 9 dürfte nun nicht mehr besonders kompliziert sein, die Lösung basiert auf einer der
angesprochenen Iterationen. Interessant an der folgenden Lösung ist vor allem, dass die Methode
den gleichen Namen besitzt, wie die bereits vorhandene Methode zum Löschen eines einzelnen
Datensatzes.
/**
* Gib alle Notizen dieses Notizbuchs auf die Konsole aus.
*/
public void zeigeNotiz()
{
int index = 0;
while(index < notizen.size()) {
zeigeNotiz(index);
index++;
}
}
Java erlaubt es den gleichen Methodennamen mehrfach zu benutzen, sofern sich zumindest der
Interface-Teil der Methoden voneinander unterscheidet, dies bezeichnet man als Polymorphie
(Vielgestaltigkeit), genauer als Methoden-Polymorphie (polymorphe Variablen werden etwas später
auftauchen).
Aufgabe 10
Erweitere das Projekt Notizbuch um eine Methode zeigeNotiz(String vergleichstext).
Aufgabe 11
Erweitere das Projekt Notizbuch um die Methoden:
– entferneNotiz() zum Löschen aller Datensätze
– entferneNotiz(String vergleichstext) zum Löschen übereinstimmender Datensätze.
Die Aufgabe 10 ist auf den ersten Blick nicht besonders spannend, da unser Notizbuch nicht mehr
speichert, als auch im Vergleichstext auftaucht. Bei komplexeren Objekten könnte man aber auf
entsprechende Art nach einem Element suchen, das einen bestimmten Feldinhalt besitzt.
Bei der Lösung der Aufgabe 10 taucht ein interessantes Problem auf, nämlich die Frage, wann zwei
Strings gleich sind.
/**
* Zeige eine Notiz.
* @param Text der Notiz, die gezeigt werden soll.
*/
public void zeigeNotiz(String vergleichstext)
{
int index = 0;
while(index < notizen.size()) {
if (vergleichstext.equals(notizen.get(index))) {
zeigeNotiz(index);
}
index++;
}
}
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 21 - Hansa-Gymnasium
/**
* Entfernt alle Notizen dieses Notizbuches.
*/
public void entferneNotiz()
{
notizen.clear();
}
/**
* Entfernt die Notiz mit dem angegebenen Text.
* @param Text der Notiz, die entfernt werden soll.
*/
public void entferneNotiz(String vergleichstext)
{
int index=0;
while (index<anzahlNotizen()) {
if (vergleichstext.equals(notizen.get(index))) {
entferneNotiz(index);
break;
}
}
}
Beim Löschen von Datensätzen taucht ein Problem auf. Der gesamte Rest der Liste verschiebt sich
und auch die Anzahl der Elemente verringert sich. Man muss daher sehr aufpassen, wie man
weiterarbeitet. Im vorliegenden Listing wurde hier der sicherste Weg gewählt, nämlich die Schleife
mittels break verlassen, wenn wenn ein Datensatz gelöscht wurde. Damit können keine Probleme
mit dem Index auftauchen, dafür wird aber nur der erste gefundene Datensatz gelöscht.
Das Definieren von mehreren Methoden bezeichnet man als Überladen. Die Methoden sind parallel
und unabhängig voneinander vorhanden. Sie müssen sich in ihrer Signatur, der Anzahl bzw. dem
Typ der Parameter, unterscheiden.
Eine Methode mit identischer Signatur kann man in abgeleiteten Klassen schrieben. Dann ist nur die
neue Methode zugänglich, die geerbte Methode aus der Ursprungsklasse ist dann nicht direkt
erreichbar. Dies bezeichnet man als Überschreiben.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 22 - Hansa-Gymnasium
7. Sitzgruppe
Im nächsten Schritt soll unser Möbelprojekt um ein zusammengesetztes Objekt erweitert werden,
eine Sitzgruppe, die z.B. aus einem Tisch und vier Stühlen besteht, analog zu Aufgabe 5.
Aufgabe 12:
Erstelle eine Klassendiagramm für das Möbelprojekt mit Sitzgruppe
Wenn man etwas über die Aufgabenstellung nachdenkt, dann kommt man schnell zu dem Schluss,
dass die Sitzgruppe selber ein Möbelstück sein muss, wie Tisch und Stuhl auch. Sie soll z.B. als
Ganzes verschoben werden können. Da sie auf der anderen Seite auch einen Tisch und vier Stühle
hat ergibt sich das folgende Klassendiagramm.
Der einfachste Ansatz zur Lösung dieser Aufgabe besteht darin Tisch und Stuhl als
Klassenvariablen einzurichten:
public class Sitzgruppe extends Moebelstueck
{
private int breite;
private int tiefe;
private Tisch tisch;
private Stuhl stuhl1;
private Stuhl stuhl2;
private Stuhl stuhl3;
private Stuhl stuhl4;
...
Damit ist dann an vielen Stellen das weitere Vorgehen klar, z.B. beim Konstruktor.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 23 - Hansa-Gymnasium
/**
* Konstruktor für Objekte der Klasse Sitzgruppe
*/
public Sitzgruppe()
{
super();
breite=220;
tiefe=230;
Dieser Teil lässt sich kaum geschickter Gestalten, da die Positionen und Ausrichtungen der
einzelnen Komponenten vorgegeben werden müssen.
Spannender wird es, wenn es an die einzelnen Nachrichten geht. Im einfachsten Fall reagiert die
Sitzgruppe auf eine Nachricht wie zeige(), indem sie diese Nachricht an ihre einzelnen
Komponenten weitergibt.
/**
* Mache dieses Objekt sichtbar. Wenn es bereits sichtbar ist, tut
* sich nichts.
*/
public void zeige()
{
istSichtbar = true;
tisch.zeige();
stuhl1.zeige();
stuhl2.zeige();
stuhl3.zeige();
stuhl4.zeige();
}
Das funktioniert für fast alle Nachrichten entsprechend. Etwas schwieriger wird es nur für alles, was
in irgendeiner Weise mit der Drehung zusammenhängt, also auch für gibAktuelleFigur().
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 24 - Hansa-Gymnasium
Wenn wir der Sitzgruppe die Nachricht dreheAuf() schicken und die Sitzgruppe diese an ihre
Komponenten weiterreicht, dann würden nur die Komponenten innerhalb der Sitzgruppe gedreht,
nicht aber die Sitzgruppe. Auf dieses Problem werden wir später noch einmal zurück kommen.
Da wir die Methode gibAktuelleFigur() unbedingt implementieren müssen, sie war in Moebelstück
nur abstrakt erklärt, hier erst einmal ein erster Ansatz, der sich weitgehend an der Methode von
Tisch und Stuhl orientiert.
/**
* Berechnet das zu zeichnende Shape anhand der gegebenen Daten
* [ Zum Anzeigen der Attributwerte über Inspect muss hier die Sichtbarkeit
* auf public gesetzt werden. ]
*/
public Shape gibAktuelleFigur()
{
GeneralPath sitzgruppe = new GeneralPath();
sitzgruppe.append( tisch.gibAktuelleFigur(), false);
sitzgruppe.append( stuhl1.gibAktuelleFigur(), false);
sitzgruppe.append( stuhl2.gibAktuelleFigur(), false);
sitzgruppe.append( stuhl3.gibAktuelleFigur(), false);
sitzgruppe.append( stuhl4.gibAktuelleFigur(), false);
return t1.createTransformedShape(sitzgruppe);
}
Aufgabe 13:
Vervollständige die Klasse Sitzgruppe, akzeptiere dabei erst einmal Probleme beim Drehen.
Hinweis:
Bei dieser Gelegenheit bietet es sich an ein kleines Designproblem aus der Klasse Moebelstuck zu
korrigieren und alle Objekte mit der Anfangsposition (0,0) zu initialisieren. Dazu müssen nur die
Werte im Konstruktor angepasst werden.
public Moebelstueck()
{
xPosition = 0;
yPosition = 0;
farbe = "blau";
orientierung = 0;
istSichtbar = false;
}
Einfacher wird es, wenn man bei Operationen über affine Transformationen regelt. Dazu sind
lediglich geringe Veränderungen an der Methode gibAktuelleFigur() notwendig.
return t1.createTransformedShape(stuhl);
}
Der Stuhl wird hier ab der Startposition (0/0) erzeugt und erst hinterher über eine Translation
verschoben.
Die überarbeitete Methode für den Tisch sieht dann folgendermassen aus.
/**
* Berechnet das zu zeichnende Shape anhand der gegebenen Daten
* [ Zum Anzeigen der Attributwerte über Inspect muss hier die Sichtbarkeit
* auf public gesetzt werden. ]
*/
public Shape gibAktuelleFigur()
{
GeneralPath tisch = new GeneralPath();
tisch.append( new Ellipse2D.Double(0 , 0, breite, tiefe), false);
return t1.createTransformedShape(tisch);
}
Hier ist übrigens gleich eine weitere kleine Inkonsistenz beseitigt, indem auch der Tisch über einen
GeneralPath erzeugt wird.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 26 - Hansa-Gymnasium
Nach diesen Änderungen lässt sich die Klasse Sitzgruppe recht einfach formulieren. Es sind nur
ganz wenige Methoden notwendig.
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.AffineTransform;
/**
*
* @author Java-MS Groupies
* hier claus albowski
* nach einer Vorlage von Uwe Debacher,
* Michael Kölling und David J. Barnes und Axel Schmolitzky
* Bearbeitung Rudolf Wilzek
* @version 1.2 (5.5.04)
*/
/**
* Konstruktor für Objekte der Klasse Sitzgruppe
*/
public Sitzgruppe()
{
// Instanzvariable initialisieren
super();
breite=220;
tiefe=230;
/**
* Hole die X-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteX()
{
return xPosition+breite/2;
}
/**
* Hole die Y-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteY()
{
return yPosition+tiefe/2;
}
}
Nicht vermeiden lässt sich die Beschreibung der Möbelgruppe, wie sie hier im Konstruktor erfolgt.
Die restlichen Operationen lassen sich aber ganz einfach erschlagen, da alle Verschiebungen und
die Drehung über gibAktuelleFigur() erledigt werden.
Hier wird zuerst ein Gesamt-Shape erzeugt, das sich aus den einzelnen Shapes zusammen setzt.
Dieses Gesamt-Shape wird dann den Transformationen unterzogen.
Dadurch ist auch gewährleistet, dass sich die Sitzgruppe um einen einheitlichen Drehpunkt dreht
und nicht die Einzel-Objekte jeweils um ihren Mittelpunkt, was nicht gewünscht wäre.
Objektorientierte Modellierung mit BlueJ
Uwe Debacher 2008 - 28 - Hansa-Gymnasium
In der bisherigen Form ist der Aufbau der Sitzgruppe recht starr, wenn man z.B. die Anzahl der
Stühle variieren will, dann muss man an mehreren Stellen im Listing Änderungen vornehmen.
Deutlich flexibler wird der Ansatz, wenn man alle Objekte in einer Liste sammelt.
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;
/**
* @author Java-MS Groupies
* hier claus albowski
* nach einer Vorlage von Uwe Debacher,
* Michael Kölling und David J. Barnes und Axel Schmolitzky
* letzte Bearbeitung Uwe Debacher
* @version 1.2 (1.6.04)
*/
/**
* Konstruktor für Objekte der Klasse Sitzgruppe
*/
public Sitzgruppe()
{
// Instanzvariablen initialisieren
super();
breite=220;
tiefe=230;
bestandteile = new ArrayList();
Moebelstueck hilf;
/**
* Hole die X-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteX()
{
return xPosition+breite/2;
}
/**
* Hole die Y-Koordinate des Mittelpunktes
* [ Hilfsfunktion für das Drehen. ]
*/
private int gibMitteY()
{
return yPosition+tiefe/2;
}
}
Von der Bedienung her ist diese Lösung vollkommen identisch zur vorherigen. Lediglich beim
Inspizieren der Variablen kann man beide Lösungen voneinander unterscheiden.
Mit diesem Ansatz wird es auch möglich Möbelstücke zur Laufzeit zu einer Gruppe hinzu zu fügen.
Dazu ist lediglich die folgende neue Methode notwendig.
Aufgabe 14:
Erweitere das Möbelprogramm um die Möglichkeit Wände zu zeichnen. Diese Wände sollen in der
Endausbaustufe auch über Durchbrüche für Türen und Fenster verfügen.