Lernziele
Wenn Sie diese Seite durchgearbeitet haben, sollten Sie
- Eine Sicherheitskopie von einem geöffneten BlueJ-Projekt anlegen können,
- eine neue Minimal-Klasse erstellen können,
- die beiden Ebenen dieser Minimal-Klasse beschreiben können,
- wissen, wie man eine neue Methode anlegt und welchen Sinn leere Methoden haben können,
- Objekte anderer Klassen in eine vorhandene neue Klasse einbinden können,
- den Begriff "HAT-Beziehung" erläutern können,
- den Unterschied zwischen einem Klassendiagramm und einem Objektdiagramm angeben können,
- begründen können, wieso man nur ein Circle-Objekt sieht, wenn man doch zwei davon angelegt hat,
- mit Hilfe des Objektinspektors die Attribute vorhandener Objekte überprüfen können,
- angeben können, welchen Nutzen Parameter beim Aufrufen von Methoden haben,
- kurz erläutern können, was man unter Refactoring versteht.
Das sind ganz schön viele Lernziele, die Sie in diesem ersten Teil des ersten Workshops erzielen können. Arbeiten Sie diesen Workshop langsam durch und lesen Sie auch das "Kleingedruckte" sorgfältig durch. Wenn im Text auf einen Lernbaustein verwiesen wird, sollten Sie sich diesen Lernbaustein ebenfalls gründlich ansehen.
In den Übungen der Folge 1 haben Sie die Methoden der Klassen Circle, Square und Triangle mithilfe der rechten Maustaste aus einem Kontextmenü ausgewählt. Wenn Sie die Farbe des Circle-Objektes sonne verändern wollten, mussten Sie erst die Methode changeColor() mit der Maus anwählen und dann in das Dialogfenster den Wert des Parameters eingeben: "yellow". Ähnlich mussten Sie bei der Änderung der Größe, der Änderung der Position und so weiter verfahren. In dieser Folge werden Sie eine völlig andere Verfahrensweise kennen lernen, mit der Sie das Gleiche sehr viel eleganter erreichen können. Sie werden programmieren!
Schritt 1 - Neue Klasse erzeugen
⇒ Öffnen Sie das Projekt "shapes" und speichern Sie mit "Speichern unter" eine Kopie des Projektes unter dem Namen "Zeichnung01" ab.
Achtung: Sie können nur auf einem Laufwerk speichern, auf dem Sie Schreibzugriff haben. Am besten nehmen Sie dafür Ihren eigenen USB-Stick oder das von den Administratoren zugewiesene Laufwerk bzw. Verzeichnis!
⇒ Klicken Sie nach dem erfolgreichen Speichern den Button Neue Klasse zur Erzeugung einer neuen Klasse an. Sie werden aufgefordert, der Klasse einen Namen zu geben und einen Typ zuzuweisen. Wählen Sie als Name Zeichnung und als Typ Class bzw. Klasse, so wie in der folgenden Abbildung gezeigt.
Erstellung einer neuen Klasse in BlueJ
Durch das Anwenden der "Speichern unter"-Funktion erstellen Sie quasi eine Sicherheitskopie des aktuellen Projektes. Der bisherige Arbeitsstand bleibt in dem Projekt "shapes" erhalten. Sie können jederzeit wieder auf dieses Projekt zurückgreifen. Die neue Version des Projektes heißt jetzt "Zeichnung01". Alle Änderungen, die Sie an "Zeichnung01" vornehmen, betreffen nicht das alte Projekt "shapes". Daher könnte man das alte Projekt durchaus als Sicherheitskopie bezeichnen.
Wenn Sie sich bei "shapes" jetzt einmal so doll "verprogrammiert" oder "verzettelt" haben sollten, dass Ihnen die Sitznachbarin oder der Lehrer oder selbst die beste Schülerin im Kurs nicht mehr weiterhelfen können, haben Sie immer noch die alte Version "shapes". Dann legen Sie einfach mit "Sichern unter" eine neue Kopie von "shapes" an und versuchen es mit dieser Kopie noch einmal.
Schritt 2 - Quelltext eingeben
⇒ Doppelklicken Sie auf den orangefarbenen Kasten der Klasse Zeichnung.
Es öffnet sich ein Editor-Fenster mit dem Quelltext der Klasse Zeichnung. In den neueren BlueJ-Versionen befindet sich der Editor in einem neuen Tab des BlueJ-Fensters:
Der Editor in einem neuen Tab des BlueJ-Fensters
Die Leute von BlueJ haben Ihnen schon etwas Arbeit abgenommen und einige Kommentare in den Quelltext eingebaut. Am besten lernen Sie Java jedoch, wenn Sie den von BlueJ erzeugten Quelltext komplett löschen (Strg-A für "alles markieren" und dann Entf für "Markierung entfernen" drücken) und dann folgenden eigenen Quelltext in das Editor-Fenster eintippen:
public class Zeichnung { public Zeichnung() { } }
⇒ Geben Sie den obigen Quelltext in das leere Editor-Fenster ein.
Dieser Quelltext der Minimal-Klasse enthält zwei Ebenen:
Die beiden Ebenen der Klasse Zeichnung
Autor: Ulrich Helmich, Lizenz: siehe Seitenende
Die erste bzw. äußere Ebene der Minimal-Klasse definiert die neue Klasse, die hier Zeichnung heißt. Die zweite bzw. innere Ebene definiert den Konstruktor der Klasse. Allerdings ist dieser Konstruktor noch leer, er besteht nur aus den beiden geschweiften Klammern, enthält aber keine Anweisungen. Daher bezeichnen wir eine solche leere aber syntaktisch völlig korrekte Klasse als Minimal-Klasse.
Wenn Sie mehr über Konstruktoren wissen wollen, klicken Sie auf den Lernbaustein "Konstruktoren".
In den neueren BlueJ-Versionen werden diese verschiedene Ebenen des Quelltext farblich sehr schön hervorgehoben:
Hervorhebung der Quelltext-Ebenen im BlueJ-Editor
Schritt 3 - Methoden
Neben dem Konstruktor haben Klassen normalerweise weitere "richtige" Methoden. Das haben wir ja in den Workshops der Folge 1 gesehen, als wir die Klassen Circle, Square und Triangle untersucht haben. Was gab es da nicht alles an Methoden!
Wir wollen die Klasse Zeichnung jetzt um eine erste "richtige" Methode ergänzen. Der Aufruf dieser Methode soll die Zeichnung auf dem Bildschirm sichtbar machen. In Anlehnung an die entsprechenden Methoden des shapes-Projektes nennen wir diese Methode ebenfalls makeVisible().
⇒ Ergänzen Sie das Projekt wie folgt:
Quelltext nach Ergänzung um die (leere) Methode makeVisible()
Es gehört zum guten Programmierstil, dass man Methoden, die in verschiedenen Klassen das Gleiche machen, auch gleich benennt. Was wäre das für ein Durcheinander, wenn Sie für eine Methode, die eine Zeichnung auf dem Bildschirm sichtbar macht, in der ersten Klasse den Namen "anzeigen()", in der zweiten Klasse den Namen "sichtbarMachen()" und in der dritten Klasse den Namen "show()" verwenden. Sie selbst und andere User des Programms kämen mit Sicherheit völlig durcheinander durch dieses Namens-Wirrwarr.
⇒ Kompilieren Sie den Quelltext, erzeugen Sie ein Objekt bild der Klasse Zeichnung, und klicken Sie dann mit der rechten Maustaste auf den roten Kasten für das Objektbild.
Tatsächlich taucht jetzt die neue Methode makeVisible() im Kontextmenü des Objektes bild auf:
Die neue Methode im Kontextmenü des Zeichnung01-Objektes "bild"
Allerdings passiert nichts, wenn Sie die Methode anwählen. Das ist aber auch kein Wunder, schließlich haben Sie noch keine Anweisungen in die Methode hineingeschrieben.
Es reicht also nicht aus, eine leere Methode im Quelltext der Klasse unterzubringen. Die Methode muss auch Anweisungen enthalten, damit sie etwas tut.
Info: Manchmal sind leere Methoden hilfreich
Manchmal ist es aber durchaus hilfreich, zunächst leere Methoden anzulegen. Eine Methode A kann nämlich andere Methoden B und C aufrufen, wie zum Beispiel hier:
public void macheMal() { macheDies(); zeigeAn(); macheDas(); zeigeAn(); }
Die Methode macheMal() ruft zunächst die Methode macheDies() auf, dann die Methode zeigeAn(), anschließend die Methode macheDas() und schließlich noch einmal die Methode zeigeAn().
Wenn jetzt die drei aufgerufenen Methoden noch gar nicht existieren würden, dann müsste der Compiler einen Fehler anzeigen:
Fehlermeldung beim Kompilieren
Daher ergänzt man die Klasse um die drei fehlenden Methoden, die aber durchaus noch leer sein können:
public void macheDies() { }
Die Methode macht noch nichts, sie verhindert aber Fehlermeldungen des Compilers, wenn eine andere Methode diese Methode benötigt.
Schritt 4 - Zwei Kreise erzeugen
Wir wollen auf unserer noch leeren Zeichenfläche jetzt zwei Objekte sichtbar machen, eine Sonne und einen Mond, so ähnlich wie in dem Workshop der Folge 1. Dazu müssen wir der Klasse Zeichnung erst einmal mitteilen, dass wir zwei Objekte der Klasse Circle benötigen, die sonne und mond heißen sollen.
⇒ Ergänzen Sie den Quelltext der Klasse Zeichnung wie folgt:
Quelltext nach Ergänzung
Hier eine kurze Erläuterung des Quelltextes:
Erläuterung des Quelltextes
Autor: Ulrich Helmich, Lizenz: siehe Seitenende
HAT-Beziehungen
Mit der Zeile
Circle sonne, mond;
bewirken wir, dass die Objekte der Klasse Zeichnung jeweils zwei Objekte der Klasse Circle haben, nämlich sonne und mond. Solch eine Beziehung zwischen Objekten nennt man eine HAT-Beziehung.
Diesen Begriff überträgt man auch auf die Klassen, von denen die Objekte abgeleitet wurden. Zwischen den Klassen Zeichnung und Circle besteht also auch eine HAT-Beziehung.
Die Hat-Beziehung als Klassendiagramm
Die Abbildung 4 zeigt ein Klassendiagramm. Klassendiagramme veranschaulichen die Beziehung zwischen zwei oder mehreren Klassen. Bei der Darstellung im Hauptarbeitsbereich von BlueJ handelt es sich auch um solche Klassendiagramme. Die HAT-Beziehung wird durch einen Pfeil dargestellt, der von der übergeordneten Klasse auf die eingebundene Klasse zeigt.
Das von BlueJ erzeugte Klassendiagramm
Immer dann, wenn eines neues Objekt einer Klasse erzeugt wird - sei es mit der rechten Maustaste wie bei BlueJ, sei es durch Ausführen einer Anweisung wie
mond = new Circle();
wird automatisch der Konstruktor dieser Klasse aufgerufen. Bei der Erzeugung des Objektes mond wird also der Konstruktor der Klasse Circle aufgerufen. Alle Anweisungen, die in diesem Konstruktor definiert sind, werden dann ausgeführt. Das Gleiche passiert in der nächsten Quelltext-Zeile, wenn das Objekt sonne erzeugt wird.
Klassendiagramme und Objektdiagramme
Das Klassendiagramm in Abbildung 10 (und auch Abbildung 11) zeigt die Beziehung zwischen den Klassen Zeichnung und Circle. Neben solchen Klassendiagrammen werden in der Informatik aber auch sogenannte Objektdiagramme eingesetzt, um komplexere Sachverhalte verständlicher zu machen. Hier sehen wir ein solches Objektdiagramm:
Die Beziehungen zwischen den Objekten bild, sonne und mond
Das Objektdiagramm ist so zu lesen: Ein Objekt bild der Klasse Zeichnung HAT zwei Objekte sonne und mond der Klasse Circle.
Sehen Sie den Unterschied zwischen dem Klassendiagramm und dem Objektdiagramm? Das Klassendiagramm stellt die Beziehungen zwischen den Klassen eines Java-Projektes dar. Da es in unserem Projekt nur die beiden Klassen Zeichnung und Circle gibt, enthält das Klassendiagramm auch nur die beiden entsprechenden Kästen.
Beim Objektdiagramm gibt es dagegen drei Kästen, denn wir haben es ja mit drei verschiedenen Objekten zu tun: bild, sonne und mond.
BlueJ kann zwar keine Objektdiagramme anzeigen, hat dafür aber einen schönen Objektinspektor. Wenn Sie einen Doppelklick auf den roten Kasten des Objektes bild ausführen, poppt ein großer roter Kasten auf, in dem alle Attribute der Klasse zu sehen sind:
Der Objektinspektor von BLueJ zeigt die beiden Objekte sonne und mond
Zukünftige Abiturienten aufgepasst!
In allen NRW-Abituraufgaben (in anderen Bundesländern wird das ähnlich sein) müssen die Kandidaten solche Diagramme beschreiben oder sogar selbst entwerfen. Gewöhnen Sie sich also rechtzeitig an Klassen- und Objektdiagramme, vor allem aber an Klassendiagramme. Die Klassendiagramme in den Abituraufgaben sind deutlich komplexer als die in diesem Kurs vorgestellten - aber sind ja auch noch ein paar Jahre hin bis zum Abitur.
Schritt 5 - Das Bild sichtbar machen
⇒ Geben Sie den neuen Quelltext aus Abbildung 8 und 9 in den BlueJ-Editor ein, falls Sie das nicht sowie schon gemacht haben.
⇒ Kompilieren Sie das Projekt und erzeugen Sie dann ein Objekt der Klasse Zeichnung. Klicken Sie mit der rechten Maustaste auf den roten Objekt-Kasten und wählen Sie aus dem Kontextmenü, welches dann erscheint, den Befehl makeVisible():
Aufruf von makeVisible() nach Erzeugung eines Objektes der Klasse Zeichnung
Was sollte nun passieren? Wir erwarten, dass zwei Kreise angezeigt werden, nämlich einer, der das Objekt mond darstellt, und ein zweiter, der das Objekt sonne zeigt.
Leider verläuft diese Sichtbarmachung nicht ganz so wie erwartet. Man sieht nicht zwei Kreise, etwa einen großen gelben und einen kleinen blauen, sondern nur einen Kreis, nämlich einen kleinen blauen:
Man sieht nur einen blauen Kreis, obwohl zwei Kreis-Objekte erzeugt wurden
Das liegt daran, dass die beiden Objekte sonne und mond absolut gleiche Attributwerte haben. Das wiederum liegt an dem Konstruktor der Klasse Circle. In diesem Konstruktor werden die Attribute auf bestimmte vordefinierte Werte gesetzt.
Wenn Sie mehr über Konstruktoren wissen wollen, klicken Sie auf den Lernbaustein "Konstruktoren".
Bei der Erzeugung der beiden Objekte sonne und mond wird ja jedes Mal der gleiche Konstruktor aufgerufen, nämlich der Konstruktor der Klasse Circle. Und dieser Konstruktor enthält bestimmte Befehle, er legt zum Beispiel fest, welche Farbe und welchen Durchmesser die erzeugten Objekte haben und an welcher Position sie auf dem Bildschirm erscheinen. Da der gleiche Konstruktor zweimal aufgerufen wird, haben auch die beiden Objekte sonne und mond die gleiche Farbe, den gleichen Durchmesser und die gleiche Position.
Wer's nicht glaubt, kann ja mal auf den roten Kasten "bild : Zeichnung" doppelklicken:
Der Objektinspektor von BlueJ zeigt die Attribute des Zeichnungs-Objektes "bild"
Der Objektinspektor
Durch einen Doppelklick auf den roten Objektkasten öffnet sich der Objektinspektor von BlueJ. Der Objektinspektor zeigt alle Attribute des Objektes an und sogar auch die aktuellen Attributwerte. Die Attribute sonne und mond sind Objekte der Klasse Circle. Die Attributwerte dieser Objekte sind recht komplex, darum werden in den weißen Kästchen nur Pfeile angezeigt, keine Werte. Man kann auf diese Pfeile aber doppelklicken:
Hier sehen wir die Attribute des Circle-Objektes sonne
Der Objektinspektor zeigt uns nicht nur die Attribute, sondern auch die Attributwerte des Objektes sonne. Der Kreis hat einen Durchmesser von 30 Pixeln und befindet sich an der Position (20,60) auf der Zeichenfläche. Die Farbe ist "blue", und er ist sichtbar: isVisible = true.
Klickt man nun auf den zweiten Pfeil, dann zeigt der Objektinspektor die Attribute und Attributwerte des Objektes mond. Wir stellen dann fest, dass die Attributwerte übereinstimmen. Das mond-Objekt befindet sich an der gleichen Position wie das sonne-Objekt und hat auch den gleichen Durchmesser.
Schritt 6 - Einen der beiden Kreise bewegen
Als Sie noch nicht programmierten, haben Sie in Folge 1, Workshop 1.2 ein Circle-Objekt bewegt, indem Sie aus dem Kontextmenü eine geeignete Methode aufgerufen haben.
Die Methode moveHorizontal() würde sich zum Beispiel gut zum horizontalen Bewegen des Kreises um eine bestimmte Pixelzahl eignen. Allerdings hat die Methode keine Ahnung, um wie viele Pixel Sie den Kreis bewegen wollen. Das müssen Sie der Methode mit Hilfe eines Parameters mitteilen.
⇒ Bauen Sie den Befehl mond.moveHorizontal(100); mit dem Parameter 100 in die Methode makeVisible() ein.
⇒ Kompilieren Sie die Klasse Zeichnung, erzeugen Sie ein Objekt dieser Klasse und führen Sie dann mit der rechten Maustaste den makeVisible()-Befehl Ihres Objektes aus.
Wenn Sie alles richtig gemacht haben, müssten Sie jetzt zwei kleine blaue Kreise auf der Zeichenfläche sehen:
Jetzt sind zwei blaue Kreise sichtbar
Der erste blaue Kreis, der für die Sonne steht, befindet sich auf der Position, die von dem Konstruktor der Klasse Circle festgelegt wurde. Der zweite blaue Kreis, der für den Mond steht, ist jedoch um 100 Pixel nach rechts versetzt worden. Das hat der moveHorizontal()-Befehl bewirkt, den Sie mit dem Parameter 100 aufgerufen haben.
In diesem Lernbaustein erfahren Sie mehr über Parameter.
Schritt 7 - Ein kleines Refactoring
Unter dem Begriff Refactoring versteht man ein "Umbauen" des Quelltextes, so dass er übersichtlicher und damit leichter verständlich wird. Die Methode makeVisible() soll ja eigentlich nur das machen, was sie verspricht, nämlich die enthaltenen Objekte sichtbar zu machen. Das horizontale Bewegen eines Objektes gehört eigentlich nicht mehr in die Methode makeVisible() sondern in eine neue Methode, die wir beispielsweise draw() nennen können. Der Quelltext der beiden Methoden sähe dann so aus:
Der optimierte Quelltext der Klasse Zeichnung
In die Methode draw() haben wir auch gleich den Befehl zum Ändern der Farbe der Sonne aufgenommen.
Wenn Sie nun ein Objekt der Klasse Zeichnung erzeugen und dann mit der rechten Maustaste zuerst die Methode makeVisible() und dann die Methode draw() aufrufen, erscheinen zwei Kreise in der Anwendung, links ein kleiner gelber, und rechts ein kleiner blauer.
⇒ Überzeugen Sie sich selbst davon, dass alles funktioniert!
Schritt 8 - Den Konstruktor die Arbeit machen lassen
Um das bisherige Programm zu testen, mussten Sie immer mit der rechten Maustaste das Kontextmenü des Objektes bild der Klasse Zeichnung aufrufen, dann den Befehl makeVisible() anwählen und anschließend den Befehl draw() aktivieren.
Diese "Mausarbeit" kann man sich erleichtern, indem man den Konstruktor diese Arbeit machen lässt. Dazu schreiben wir einfach die beiden genannten Befehle in den Konstruktor:
Der erweiterte Konstruktor
Wenn wir jetzt ein neues Objekt der Klasse Zeichnung erzeugen, dann erscheint sofort ein kleines Fenster auf dem Bildschirm und zeigt uns die beiden Kreise an. Wir müssen nicht mehr mit der Maus die beiden Methoden in dem Kontextmenü aktivieren, das erspart uns in Zukunft viel Zeit.
Übungen
Übung 2.1-1
- Deklarieren Sie in der Klasse Zeichnung folgende Objekte: Einen Kreis namens sonne, einen zweiten Kreis namens mond, ein Quadrat namens haus und ein Dreieck namens dach.
- Erzeugen Sie die vier Objekte im Konstruktor der Klasse Zeichnung mit dem new-Befehl.
- Erweitern Sie die Methode makeVisible() der Klasse Zeichnung so, dass alle vier Objekte sichtbar werden.
- Erweitern Sie die Methode draw()so, dass ein kleines Bild gezeichnet wird: Ein Haus mit einem Dach und einem Mond und einer Sonne am Himmel, ähnlich wie in der Folge 1. In dieser Methode müssen nun die manipulierenden Methoden der einzelnen Objekte in der richtigen Reihenfolge und mit den richtigen Parametern aufgerufen werden, damit eine schöne Zeichnung entsteht.
Zu den Lösungen...
Wir sind noch nicht fertig mit unserem Projekt. Hier kommen Sie zum zweiten Teil des Workshops "Wir programmieren ein Bild".
Seitenanfang -
Weiter mit Teil 2 dieses Workshops...