Skip to content

4.2 Grundlagen zu eigenen Klassen

In der objektorientierten Programmierung gilt das Paradigma: Programmiere eine Klasse, erstelle viele Objekte. Der Vorteil dieser Vorgehensweise ist die Wiederverwendbarkeit: Anstatt jedes Objekt einzeln zu programmieren, kann ein Bauplan genutzt werden, um viele Objekte dieser Klasse zu erzeugen. Der Bauplan selbst muss nur einmal implementiert werden.
Die Siedlung am Wald ist ein gutes Beispiel für die Sinnhaftigkeit dieses Vorgehens: Die Siedlung besteht aus mehreren Häusern und Bäumen. Man könnte nun wie im Projekt Landschaft vorgehen und den Quelltext zur Erstellung des Hauses vervielfältigen (z.B. per Copy & Paste) und jeweils die Position der einzelnen Bausteine wie Dach und Tür anpassen. Allerdings birgt das Vorgehen enorme Nachteile:

  • Wenn das Haus verändert werden soll, indem beispielsweise die Farbe oder die Größe der Fenster modifiziert wird, muss dies an vier Stellen statt an einer Stelle erfolgen, um alle Häuser zu ändern. Neben dem Aufwand ist hier vor allem die Fehleranfälligkeit von Nachteil.
  • Der Quelltext wird deutlich länger und damit schlechter lesbar.

Stattdessen macht es Sinn, eine Klasse Haus und eine Klasse Baum zu erstellen. Von diesen Klassen können dann viele Objekte erzeugt werden.

siedlung

Hinweis

Wenn beim Progammieren intensiv Copy & Paste genutzt wird, kann das ein Anzeichen dafür sein, dass vom objektorientierten Ansatz der Programmierung abgewichen wird.

Prinzipien der objektorientierten Programmierung

Beim Klassenentwurf verfolgt man in der objektorientierten Programmierung zudem die beiden folgenden Prinzipien:

Prinzip der verteilten Intelligenz / Autonomitätsprinzip: Objekte sollen sich selbst verwalten, wann immer es möglich ist. Sie werden bestenfalls nicht „von außen“ gesteuert. Zur Kommunikation mit anderen Objekten stellen sie Methoden zur Verfügung.

Datenkapselung / Geheimnisprinzip: Eine Klasse soll nur so viel über ihre Wirkungsweise „veröffentlichen“, wie zur Erfüllung ihrer Aufgaben nötig ist. Was vor der Außenwelt verborgen werden kann, soll verborgen werden.

verteilte intelligenz

Klassenentwurf

Zur Modellierung der Siedlung am Wald greifen wir wieder auf die Fragen zurück, die wir bereits beim Erstellen der ersten Landschaft verwendet haben.

    1. Die erste Frage lautet: Aus welchen Objekten besteht diese Klasse? Für die Klasse Baum lässt sich das schnell beantworten: Ein Baum besteht aus einer krone, die als Objekt der Klasse SGKreis modelliert werden kann, und einem stamm, also einem Objekt der Klasse SGRechteck.
    2. Die zweite Frage zielt auf den Konstruktor der Klasse: Mit welchen Anfangswerten müssen die Objekte erzeugt werden? Diese Frage ist schwieriger zu beantworten. Beim Erzeugen eines Baum-Objekts sind Farbe und Größe für alle Objekte gleich, sie können im Konstruktor mit den entsprechenden Anweisungen festgelegt werden. Allerdings unterscheiden sich Baum-Objekte in ihrer Position, die jedem Baum-Objekt individuell zugewiesen werden muss.
      Der Konstruktor der Klasse Baum muss also so gewählt werden, dass die Position des Baumes als Parameter übergeben werden kann. Im Konstruktor werden dann die Parameter genutzt, um den Baum zu positionieren.
    3. Die dritte Frage lautet: Wie müssen die Objekte nach ihrer Erzeugung verändert werden? Wenn es beispielsweise möglich sein soll, die Bäume zu fällen, muss die Klasse Baum eine Methode faelleBaum() implementieren, in der krone und stamm um 70° gedreht werden.

Damit gelangt man zum nebenstehenden UML-Implementationsdiagramm.

siedlung
umlBaum
umgefalleneBaeume

Implementation der Klasse

Die Klasse Baum kann auf der Grundlage des UML-Diagramms implementiert werden. Der Großteil der Anweisungen ist bereits aus vorherigen Projekten bekannt. Interessant mit Blick auf die Verwendung eigener Klassen sind die Zeilen 5, 6 und 9 des folgenden Quelltextes.

    public class Baum {
    private SGRechteck stamm;
    private SGKreis krone;

    public Baum(int pX, int pY) {
        krone = new SGKreis(pX,pY,40);
        krone.setzeFuellung(true);
        krone.setzeFarbe(0.1,0.9,0.5);
        stamm = new SGRechteck(pX+30,pY+40,20,80);        
        stamm.setzeFuellung(true);        
        stamm.setzeFarbe(0.7,0.7,0.1);
    }
    
    public void faelleBaum() {
        double tempX = stamm.gibX() + stamm.gibBreite()*0.5;
        double tempY = stamm.gibY() + stamm.gibHoehe();
        stamm.dreheUmPunkt(70, tempX, tempY);
        krone.dreheUmPunkt(70, tempX, tempY);
    }
}   
            
                    
        

Bei der Zeile 5 handelt es sich um den Konstruktor. Anders als bei bisher programmierten Klassen finden sich hier in den Klammern Parameter. Dabei handelt es sich um Variablen, denen beim Aufruf des Konstruktors ein Wert zugewiesen werden muss. Sie dienen also als Platzhalter, um dynamisch Werte beim Erzeugen eines Objekts festzulegen.

In unserem Fall wird erst beim Erzeugen eines Baum-Objekts die Position festgelegt, da diese sich für alle Baum-Objekte unterscheiden soll. Entsprechend finden sich im Konstruktor zwei Parameter, einmal pX für die x-Position und pY für die y-Position.

Diese beiden Variablen werden auch in den Anweisungen in Zeile 6 und 9 genutzt, wenn die Position von krone und stamm festgelegt wird. Die Werte in pX und pY werden dabei genutzt, um die Position der Objekte zu berechnen.

Die Erzeugung eines Baums erfolgt in der Klasse Landschaft zum Beispiel mit der folgenden Anweisung:

meinBaum = new Baum(500,200);

Beim Ausführen des Konstruktors werden nun die Parameter pX und pY mit den Werten 500 und 200 gefüllt. Die Variablen pX und pY stehen nun innerhalb des Konstruktors zur Verfügung: An jeder Stelle, an der diese Variablen genutzt werden, werden zur Laufzeit die angegebenen Werte eingesetzt. Die Anweisung in Zeile 14 wird für das obige Beispiel zu:

stamm = new SGRechteck(500+30,200+40,20,80);

hausbaumwolke

Eigene Klassen erstellen

1 / 7

Welche Vorteile bietet es, für das Haus oder den Baum eine eigene Klasse zu erstellen?

2 / 7

Indem die Attribute einer Klasse mit der Sichtbarkeit private deklariert werden, werden die Daten gekapselt und das Geheimnisprinzip umgesetzt.

3 / 7

Bei dem Baum soll die Krone über den Stamm gezeichnet werden. Dafür muss die Ebene der Krone gesetzt werden. In welcher Klasse wird diese Anweisung gegeben.

4 / 7

Der Konstruktor einer Klasse Windrad könnte zum Beispiel so aussehen:

public Windrad(int pX, int pY, double pGeschwindigkeit)

Bei pX, pY und pGeschwindigkeit handelt es sich um dieser Methode. Beim Aufruf des Konstruktors können dann hierfür Werte übergeben werden, um zusätzliche Informationen zur Verfügung zu stellen. Es handelt sich also um . Im Gegensatz zu einem , das üblicherweise zu Beginn im Klassenrumpf deklariert werden, handelt es sich hier um , die nur im Konstruktor zur Verfügung stehen.

Einzusetzende Begriffe: Parameter, temporäre Variablen, Attribut, Variablen

5 / 7

Welcher der folgenden Konstruktoren gehört zu dem folgenden Methodenaufruf

meinBaum = new Baum(50,300,true);

6 / 7

Überprüfe, ob die folgenden Aussagen für den im Bild gezeigten Klassenentwurf zutreffen.

7 / 7


Gib an, welche Attribute in der Klasse Windrad benötigt werden.

Dein Ergebnis ist

Die durchschnittliche Punktzahl ist 68%

0%