Informatik-Lexikon

Klasse

Aufbau einer Java-Klasse

Gliederung

Aufbau einer Java-Klasse

Attribute

1. primitive Attribute

2. Referenzattribute

Konstruktoren

1. Allgemeines

2. Overloading von Konstruktoren

Methoden

1. Datenkapselung

2. Verändernde Methoden

3. Abfragende Methoden

4. Weitere Methoden

1 Aufbau einer Java-Klasse: Attribute - Konstruktor(en) - Methoden

Attribute

1. primitive Attribute^

Das sind Attribute, in denen einfache Daten gespeichert werden:

Für einfache Attribute passt auch die Barnes/Kölling-Definition gut: "Datenfelder sind kleine Bereiche innerhalb eines Objektes, in denen Werte gespeichert werden können."

Solche Werte haben wir bisher als Attributwerte bezeichnet. Attribute müsse nicht vom Typ int sein, sondern es können auch String- oder float-Attribute oder komplizierter aufgebaute Attribute sein.

2. Referenz-Attribute^

Neben den primitiven Attributen können auch Objekte anderer Klassen als Attribute auftreten; man spricht dann von Referenz-Attributen.

In der Folge 2 (siehe PDF-Version) haben wir die Klasse Zeichnung mit zwei Referenz-Attributen ausgestattet: sonne und haus. Bei diesen Referenz-Attributen handelt es sich um Objekte der Klassen Kreis bzw. Quadrat.

Konstruktoren

1. Allgemeines^

Jede Klasse muss mindestens einen Konstruktor haben. Es sind auch mehrere Konstruktoren möglich, die sich dann aber in ihren Parameterlisten unterscheiden müssen. Der Konstruktor muss genau so heißen wie die Klasse; auch auf Groß- und Kleinschreibung ist dabei zu achten.

Der Konstruktor ist eine besondere Methode, die zum Erzeugen von Objekten dient. Möchte der Benutzer der Klasse hier irgendwie steuernd eingreifen, also zum Beispiel bestimmte Werte selbst bestimmen, so geschieht das mit Hilfe von Parametern.

Bei unserer Klasse Auto aus Folge 4 hat der Konstruktor zwei Parameter. Wenn ein neues Auto-Objekt erzeugt wird, können wir direkt beim Erzeugen festlegen, wieviel Liter Benzin im Tank des Wagens sind und wie hoch der aktuelle Kilometerstand ist.

2. Overloading von Konstruktoren^

Eine Klasse kann mehrere Konstruktoren haben, die sich dann aber in ihren Parameterlisten unterscheiden müssen. Das kann unter Umständen sehr vorteilhaft sein. Für die Klasse Auto könnte man z.B. drei Konstruktoren schreiben:
public Auto()
public Auto (float benz)
puclic Auto (float benz, int km)

Ruft man die erste Methode auf, so würden Benzinstand und Kilometerstand auf irgendwelche default-Werte gesetzt, z.B. auf 50 bzw. 10.000. enn man die zweite Methode aufruft, so wird der Benzinstand aus dem Parameter ausgelesen, während der Kilometerstand auf den default-Wert 10.000 gesetzt wird. Und wenn man die dritte Methode aufruft, so werden beide Parameter ausgewertet. Näheres zum Overloading von Konstruktoren erfahren Sie auf der Theorieseite.

Methoden

Bevor wir auf Methoden zu sprechen kommen, soll ein sehr wichtiges allgemeines Prinzip erläutert werden, nämlich das Prinzip der Datenkapselung.

1. Datenkapselung^

Das Prinzip der Datenkapselung ist derart wichtig, dass es in einen eigenen Teil ausgelagert wurde. Dort können die Einzelheiten nachgelesen werden.

2. Verändernde Methoden (Mutator-Methoden)^

Manche Attribute müssen verändert werden, wenn man dem Objekt Leben einhauchen will. Wenn man eine Klasse Kreis und ein davon abgeleitetes Objekt ball hat, so will man den Ball auf dem Bildschirm bewegen können. Dazu muss man das Attribut xpos und das Attribut ypos des Ball-Objektes verändern können.

Man könnte nun einfach das Attribut xpos zu einem public-Attribut machen. Technisch ist dies möglich, aber sehr riskant! Jede Methode einer Klasse, die jetzt Zugriff auf Kreis-Objekte hat, kann nach Belieben die öffentlichen Attribute verändern und auf Werte setzen, die überhaupt keinen Sinn machen.

Stellen Sie sich vor, das Spielfeld für den Ball ist nach links und rechts begrenzt. Die niedrigste x-Koordinate soll 0 sein, die höchste 640. Wenn sich der Ball nun an Position x = 500 befindet, kann er sich eigentlich nur noch 140 Pixel nach rechts bewegen. Ist das Attribut xpos nun öffentlich zugänglich, so könnte eine falsch programmierte FOR-Schleife die X-Position um 300 Werte erhöhen. Der Ball befände sich plötzlich auf der Position x = 800, die überhaupt nicht definiert ist.

Aus diesem Grund sollten alle Attribute eines Objektes als privat deklariert werden - es sei denn, Sie sind sich ganz sicher, dass nichts gegen eine Veröffentlichung des Attributes spricht. Aber lesen Sie vorher folgendes Zitat: "Das ist der ganze Jammer: die Dummen sind so sicher und die Gescheiten so voller Zweifel!" (Bertrand Russell).

Wenn Sie ein Attribut verändern wollen, so müssen Sie dazu eine spezielle Methode programmieren, die bei Bedarf bestimmte Kontrollstrukturen zur Verfügung stellt, damit das Attribut nicht auf unerlaubte Werte gesetzt wird.

In unserem Beispiel mit dem Ball könnte die Methode zum Verändern der X-Position zum Beispiel so aussehen:

public void nachLinks(int strecke)
{
   if (xpos + strecke <= 640)
      strecke += xpos;
}
So ganz fehlerfrei ist diese Methode noch nicht; wenn zum Beispiel jemand den Wert -1000 als Parameter wählt, so wird die X-Position auf einen negativen Wert gesetzt, was natürlich nicht sein darf. Also müsste die Kontrollstruktur noch etwas verfeinert werden.

3. Abfragende Methoden (Observer-Methoden)^

Wenn Sie wissen wollen, an welcher X-Position sich das Kreis-Objekt ball gerade befindet, so könnten Sie theoretisch direkt auf das Attribut xpos zugreifen. Das geht aber nur dann, wenn dieses Attribut nicht als privat deklariert wurde. Wenn Sie sich aber an das Prinzip der Datenkapselung gehalten haben, so ist eine solche Abfrage nicht möglich, denn nach außen hin ist das Attribut nicht mehr sichtbar.

Also müssen Sie abfragende Methoden konstruieren, die für Sie diese Arbeit übernehmen. BARNES und KÖLLIG sprechen hier von sondierenden Methoden. Für die X-Position eines Kreis-Objektes könnte die Abfragemethode zum Beispiel so aussehen:

public int getXPos()
{
   return xpos;
}

Soll bei einem Gegenstand aus dem Adventure-Spiel abgefragt werden, ob es sich um eine Waffe handelt, so geht das so:

public boolean istWaffe()
{
   return (typ == 1)
}
Es wird einfach abgefragt, ob der Typ des Gegenstandes den Wert 1 hat. Der Wahrheitswert, den dieser Vergleich liefert, wird als Funktionsargument zurückgegeben. Gilt typ == 1, so wird true zurückgeliefert, andernfalls false.

4. Weitere Methoden^

Neben den verändernden Methoden und den abfragenden Methoden sind weitere Arten von Methoden in Java (und anderen Programmiersprachen) denkbar.

Allgemein haben Methoden eine ganz bestimmte Aufgabe in der Programmierung einer Klasse. Rein theoretisch könnte eine Klasse aus den Attributen, dem Konstruktor sowie einer oder zwei weiteren Methoden bestehen. Komplexe Klassen haben aber mehr als eine oder zwei Aufgaben zu erledigen, entsprechend hoch ist dann auch die Zahl der Methoden. Manche Aufgaben sind aber so komplex, dass man sie besser in zwei, drei Methoden zerlegt: Eine öffentliche (public) Schnittstellen-Methode, die die Befehle aus der Außenwelt in Form von Parametern entgegennimmt, sowie eine oder zwei nicht-öffentliche (private) Hilfsmethoden, die von der öffentlichen Methode aufgerufen werden, nach außen hin aber nicht in Erscheinung treten.

Als erstes Beispiel wollen wir eine mathematische Funktion betrachten, die die Entfernung eines Kreis-Objekts vom rechten Rand der Zeichenfläche berechnet:

public int getDistanceXR()
{
   return 640 - xpos;
}

Was ist das für eine Methode? Es wird hier etwas abgefragt, nämlich die Entfernung des Kreis-Objektes vom rechten Rand der Zeichenfläche. Aber die Methode ist keine abfragende Methode in dem Sinne, dass der Wert eines Attributes zurückgeliefert wird.

Der Attributwert fließt in eine Berechnung ein, deren Ergebis dann zurückgeliefert wird.

Unser zweites Beispiel ist reichlich konstruiert, soll aber verdeutlichen, was alles in Java möglich ist (ob es sinnvoll ist, ist eine andere Sache).

public int nachLinks(int strecke)
{
   if (xpos + strecke <= 640)
   {     
      xpos += strecke;
      return xpos;
   }
}

Diese seltsame Methode verändert nicht nur das Attribut xpos, sondern liefert gleichzeitig seinen (neuen) Wert zurück. Es handelt sich also um eine abfragende und verändernde Methode. Sehr elegant ist so etwas nicht, und ich werde eine solche Programmierweise negativ bewerten, sollte ich etwas Ähnliches in einer Lösung entdecken.





IMPRESSUM