Home > Informatik > Stufe EF > Folge 2 > Folge 2.1

2.1 Wir programmieren ein Bild

Was Sie lernen werden

Wenn Sie diese Seite durchgearbeitet haben, werden Sie in der Lage sein:

  • eine neue Java-Klasse zu erstellen,
  • einen Konstruktor für diese Klasse zu schreiben,
  • Methoden für diese Klasse zu schreiben,
  • Objekte anderer Klassen in eine vorhandene neue Klasse einzubinden und
  • deren Methoden zielgerichtet mit geeigneten Parametern aufzurufen.

Rückblick auf Folge 1

In den beiden Workshops der ersten Folge haben Sie die Methoden der Klassen Circle, Square und Triangle über das Kontextmenü mit einem Rechtsklick ausgewählt.

Wenn Sie zum Beispiel die Farbe des Circle-Objekts sonne ändern wollten, haben Sie zunächst die Methode changeColor() mit der Maus ausgewählt und anschließend im Dialogfenster den gewünschten Farbwert – etwa "yellow" – eingegeben. Ähnlich gingen Sie auch bei Größenänderungen, Positionsänderungen und anderen Anpassungen vor.

In dieser Folge lernen Sie nun einen ganz neuen Weg kennen, der Ihnen deutlich mehr Freiheiten bietet – und das auf elegante Weise: Sie werden Ihr erstes Java-Programm erstellen.

Das heißt: Sie werden die Methoden der Objekte sonne, mond, haus und dach nicht mehr über ein Kontextmenü aufrufen, sondern aus einem Java-Programm heraus, das Sie selbst schreiben werden.

Schritt 1 - Neue Klasse erzeugen

⇒ Öffnen Sie das Projekt "shapes" und erstellen Sie mit "Speichern unter..." eine Kopie des Projektes unter dem Namen "Folge_2_1" ab.

Falls Sie in der Schule, der Hochschule oder der Firma an einem Rechner sitzen, der Ihnen nicht gehört, müssen Sie darauf achten, dass Sie Schreibrechte für das gewählte Laufwerk besitzen. Wenn das nicht der Fall ist, können Sie es mit einem USB-Stick oder einer portablen SSD versuchen. Wenn das auch nicht möglich ist - manche Firmen verbieten externe Speichermedien aus Sicherheitsgründen - wenden Sie sich an die verantwortlichen Admins.

⇒ Klicken Sie anschließend auf den Button Neue Klasse. Geben Sie der neuen Klasse den Namen Zeichnung und wählen Sie als Typ Klasse (Class), wie in der folgenden Abbildung dargestellt.

Erzeugen einer neuen Klasse in BlueJ wie im obigen Text besprochen.

Erstellung einer neuen Klasse in BlueJ

Durch den Befehl Speichern unter… erstellen Sie eine Kopie des bisherigen Projekts. Das ursprüngliche Projekt bleibt dabei unverändert erhalten und kann jederzeit wieder geöffnet werden. Alle Änderungen, die Sie im Projekt Folge_2_1 vornehmen, wirken sich ausschließlich auf diese neue Projektkopie aus.

Schritt 2 - Quelltext eingeben

⇒ Doppelklicken Sie auf den orangefarbenen Kasten der Klasse Zeichnung.

Es öffnet sich der Editor mit dem Quelltext der neuen Klasse

BlueJ erzeugt automatisch einen kleinen Kommentar. Für unsere Übungen benötigen wir diesen jedoch nicht.

⇒ Löschen Sie daher den gesamten Quelltext und geben Sie stattdessen den folgenden Quelltext ein:

public class Zeichnung
{
    public Zeichnung() 
    {
    }

}

Diese Klasse enthält zunächst nur das Nötigste: die Klasse Zeichnung und einen leeren Konstruktor. Da der Konstruktor noch keine Anweisungen enthält, passiert beim Erzeugen eines Objekts zunächst noch nichts.

In aktuellen BlueJ-Versionen werden die verschiedenen Bereiche des Quelltextes farblich hervorgehoben. Der äußere Bereich gehört zur Klasse Zeichnung, der innere Bereich zum Konstruktor Zeichnung().

Beschreibung siehe folgenden Text

Hervorhebung der Quelltext-Ebenen im BlueJ-Editor

Der äußere Rahmen der gesamten Klasse ist hier grün hervorgehoben. Der Konstruktor der Klasse ist dagegen gelb markiert.

Exkurs:
Konstruktoren

Wer es unbedingt schon wissen möchte: Zu einer Klasse gehören verschiedene Methoden. Die Klassen Circle und Square beispielsweise besitzen die manipulierenden Methoden changeColor() und changeSize(). Diese Methoden können bei Bedarf aufgerufen werden.

Der Konstruktor dagegen wird automatisch ausgeführt, wenn ein neues Objekt einer Klasse erzeugt wird. Seine Aufgabe besteht darin, das neu erzeugte Objekt zu initialisieren.

Konstruktoren

Wenn Sie mehr über Konstruktoren wissen wollen, klicken Sie auf den Lernbaustein "Konstruktoren".

Schritt 3 - Zwei Kreise erzeugen

⇒ Ergänzen Sie das Projekt wie folgt:

public class Zeichnung
{
    Circle sonne, mond;
    
    public Zeichnung()
    {
       sonne = new Circle();
       mond  = new Circle();
       sonne.makeVisible();
       mond.makeVisible();
    }
}

⇒ Kompilieren Sie den Quelltext, öffnen Sie das Kontextmenü der Klasse Zeichnung und wählen Sie dann den Befehl new Zeichnung().

Wenn Sie alles richtig gemacht haben, erscheint jetzt ein kleines weißes Fenster mit einem kleinen blauen Kreis in der linken oberen Ecke. Eigentlich sollten wir dort zwei Kreise sehen, aber man sieht nur den einen Kreis.

Bevor wir uns um die Frage kümmern, warum man nur einen Kreis sieht, wollen wir den aktuellen Quelltext der Klasse Zeichnung besprechen.

Quelltext-Besprechung

Wir haben die Klasse Zeichnung um zwei Instanzvariablen der Klasse Circle ergänzt. Dies geschieht in der Zeile

Circle sonne, mond;

Diese Zeile ist eine Deklaration von zwei Instanzvariablen. Wir teilen dem Programm mit, dass wir zwei Variablen der Klasse Circle benötigen und dass diese Variablen die Namen sonne bzw. mond haben sollen.

Im Konstruktor von Zeichnung werden diese beiden Variablen dann initialisiert. Dies geschieht in den beiden Zeilen

sonne = new Circle();

und

mond = new Circle();

Durch diese beiden Anweisungen werden im Speicher zwei Circle-Objekte erzeugt und deren Adressen den Instanzvariablen sonne und mond zugewiesen. Erst jetzt können wir Methoden dieser Objekte aufrufen.

In den beiden letzten Zeile des Konstruktors versuchen wir, die zwei Objekte sichtbar zu machen. Dazu rufen wir für jedes Objekt die Methode makeVisible() auf:

sonne.makeVisible();

und

mond.makeVisible();

Eines dieser beiden Objekte können wir dann tatsächlich in dem weißen Fenster sehen, das andere Objekt noch nicht.

Warum kann man nur ein Objekt sehen?

Beim Erzeugen eines Circle-Objekts wird automatisch der Konstruktor der Klasse Circle ausgeführt. Dieser weist jedem neuen Kreis dieselbe Anfangsposition links oben zu. Da sowohl sonne als auch mond an derselben Stelle erzeugt werden und außerdem die gleiche Größe besitzen, liegen beide Kreise übereinander. Deshalb ist im Zeichenfenster nur ein einziger Kreis zu sehen.

Merke:

Objekte erzeugen

Mit new Circle() wird ein neues Objekt erzeugt. Erst danach können Methoden dieses Objekts aufgerufen werden.

Exkurs für Interessierte:
Instanzvariablen als Referenzen auf Objekte

Das folgende Bild zeigt den Zusammenhang zwischen den Begriffen Instanzvariable und Objekt.

Instanzvariablen und Objekte
Autor: Ulrich Helmich 07/2026, Lizenz: Public domain

Die Instanzvariablen sonne und mond kann man sich wie kleine Zettel vorstellen, auf denen notiert ist, an welcher Stelle im Speicher (an welcher Adresse) sich die konkreten Objekte befinden.

Direkt nach der Deklaration

Circle sonne, mond;

besitzen die beiden Instanzvariablen zunächst noch keine Referenz auf ein Objekt (haben also noch keine Adresse gespeichert). Ihr Wert ist null. Man kann sich das so vorstellen, als wären die beiden Zettel noch leer.

Nach der Initialisierung

sonne = new Circle();

mond = new Circle()

enthalten die beiden Instanzvariablen jeweils eine Referenz auf das zugehörige Objekt (sie kennen jetzt die Speicheradressen). Man sagt auch: Die Instanzvariablen verweisen auf oder referenzieren die Objekte. Aus diesem Grund werden Instanzvariablen, deren Datentyp eine Klasse ist, häufig auch als Referenzvariablen bezeichnet.

Merke:

Instanzvariablen sind Referenzen

Bei Klassen speichert eine Instanzvariable nicht das Objekt selbst, sondern eine Referenz auf dieses Objekt.

Schritt 4 - Beide Kreise sichtbar machen

⇒ Ergänzen Sie den Quelltext der Klasse Zeichnung folgendermaßen:

public class Zeichnung
{
    Circle sonne, mond;
    
    public Zeichnung()
    {
       sonne = new Circle();
       mond  = new Circle();
       sonne.makeVisible();
       mond.makeVisible();
       sonne.moveHorizontal(100);
       sonne.changeColor("yellow");
       sonne.changeSize(80);
       mond.changeSize(30);
    }
}

Nachdem beide Objekte erzeugt und sichtbar gemacht wurden, verändern wir ihre Eigenschaften.

Die Sonne wird nach rechts verschoben: sonne.moveHorizontal(100);

erhält die Farbe Gelb: sonne.changeColor("yellow");

und wird vergrößert: sonne.changeSize(80);

Den Mond lassen wir dagegen etwas kleiner werden:

mond.changeSize(30);

⇒ Übersetzen Sie den Quelltext erneut und erzeugen Sie anschließend ein neues Objekt der Klasse Zeichnung.

Jetzt erscheint links im Zeichenfenster ein kleiner blauer Mond und rechts davon eine größere gelbe Sonne.

Schritt 5 - Quelltext übersichtlicher gestalten

Der Quelltext der Klasse Zeichnung funktioniert fehlerfrei. Eine Sache stört allerdings: Der Konstruktor enthält inzwischen sehr viele Anweisungen. Die Aufgabe eines Konstruktors ist es, ein neu erzeugtes Objekt in einen geordneten Anfangszustand zu versetzen. Dies geschieht in der Regel dadurch, dass die wichtigen Instanzvariablen initialisiert werden.

Der Konstruktor der Klasse Zeichnung leistet aber wesentlich mehr. Er macht die Objekte sonne und mond sichtbar und er verändert das Position, die Größe und die Farbe des Objekts sonne sowie die Größe des Objekts mond. Dadurch wird der Konstruktor unnötig lang und verliert an Übersichtlichkeit.

Solche Methodenaufrufe sollten eigentlich in eine eigene Methode ausgelagert werden, die dann vom Konstruktor aufgerufen wird.

Verändern Sie den Quelltext der Klasse Zeichnung wie folgt:

public class Zeichnung
{
    Circle sonne, mond;

    public Zeichnung()
    {
        sonne = new Circle();
        mond  = new Circle();
        initialisiereSonne();
        initialisiereMond();
    }

    public void initialisiereSonne()
    {
        sonne.makeVisible();
        sonne.moveHorizontal(100);
        sonne.changeColor("yellow");
        sonne.changeSize(80);
    }

    public void initialisiereMond()
    {
        mond.makeVisible();
        mond.changeSize(30);
    }

}

Der Konstruktor ist jetzt wesentlich kürzer und leichter zu verstehen. Die eigentliche Arbeit wird auf zwei Methoden verteilt, deren Namen sofort erkennen lassen, welche Aufgabe sie erfüllen.

Eine solche Umstrukturierung des Quelltextes bei unverändertem Programmverhalten bezeichnet man als Refactoring.

Hinweis für Lehrende

Der erste Quelltext dieser Folge enthält bewusst einen sehr umfangreichen Konstruktor. Aus Sicht der Softwaretechnik wäre es sinnvoller, die Methoden initialisiereSonne() und initialisiereMond() von Anfang an einzuführen oder die gesamte Initialisierung anders zu strukturieren.

Didaktisch bietet der zunächst längere Konstruktor jedoch mehrere Vorteile:

  • Die Schüler(innen) erkennen zunächst, dass Methodenaufrufe einfach nacheinander ausgeführt werden.
  • Der Zusammenhang zwischen Objekterzeugung (new Circle()) und Methodenaufrufen (makeVisible(), changeColor(), changeSize()) bleibt unmittelbar sichtbar.
  • Erst nachdem dieses Prinzip verstanden wurde, wird der Quelltext in kleinere, übersichtlichere Methoden zerlegt.

Auf diese Weise erleben die Schüler(innen) den Nutzen einer Umstrukturierung unmittelbar. Der Fachbegriff Refactoring wird so anhand eines konkreten Beispiels erläutert.

Übungen

Aufgabe 1

Bearbeiten Sie die Klasse Zeichnung nun so, dass ähnlich wie in der Folge 1 ein Bild gezeichnet wird: Ein Haus mit einem roten Dach, am Himmel ein kleiner blauer Mond und eine große gelbe Sonne,

Seitenanfang -
Weiter mit HAT-Beziehungen und Klassendiagrammen ...