04.03.03 Methoden
Sie wissen nun bereits, dass Attribute den Zustand eines Objektes beschreiben. Um aber effektiv mit Objekten zu arbeiten, fehlt noch das zugehörige Verhalten. Dies wird durch die Definition von Methoden ermöglicht.
Methoden
Methoden beschreiben das Verhalten eines Objektes und werden Objektmethoden genannt. Ein Sonderfall sind die Klassenmethoden (siehe Kapitel 04.03.07 Verwendung von static). Methoden arbeiten meist mit den Attributen um etwas Bestimmtes zu erreichen. Dies können Berechnungen, Ausgaben, Datenbankzugriffe usw. sein.
Wie Sie vielleicht noch aus Kapitel 04.03.01 Allgemeines zu Klassen wissen, sind Methoden Bestandteil des Klassenrumpfes. Ihre Deklaration folgt ebenfalls einem Muster.
[Modifizierer] Rückgabetyp name ([Parameterliste]) {}
Eine Methode besteht somit aus den optionalen Modifizierern , dem Rückgabetyp, einem Namen und einer optionalen Parameterliste. Dies alles wird als Methodenkopf bezeichnet. Die Methodensignatur besteht aus dem Namen und der Parameterliste – die Modifizierer und der Rückgabetyp gehört nicht mit zur Signatur. Sie wird dazu verwendet, um sicher zu stellen, dass es nur eine solche Methode pro Klasse gibt. Der sogenannte Methodenrumpf, welcher das Verhalten einer Methode enthält, befindet sich nach dem Methodenkopf innerhalb geschweifter Klammern. Die Vergabe eines Methodennamens sollte dabei den 07.05 Code Conventions folgen.
Methoden stellen die Schnittstellen eines Objektes dar.
Als Beispiel erweitern wir nun die Klasse Punkt
aus unserem Kapitel 04.03.02 Attribute um die Verwendung von Methoden zu demonstrieren.
public class Punkt { private int x = 10; private int y = 20; public void ausgabe() { System.out.println("x-Wert: " + this.x); System.out.println("y-Wert: " + this.y); } }
Als erste Änderung dürfte Ihnen auffallen, dass der Modifizierer public
bei den Attributen x
und y
verschwunden ist und durch private
ersetzt wurde, da wir nicht mehr direkt von Außen auf diese zugreifen wollen (näheres hierzu siehe Kapitel 04.03.06 Sichtbarkeitsmodifizierer). Zusätzlich haben diese Attribute aber einen Initialwert erhalten, nämlich „10“ für das Attribut x
und „20“ für das Attribut y
. Die größte Änderung besteht aber aus der neu hinzu gekommenen Methode ausgabe
. Innerhalb dieser Methode werden nun die Werte der Attribute x
und y
ausgegeben.
Dies entspricht der gleichen Ausgabe des Beispiels in Kapitel 04.03.02 Attribute innerhalb der dortigen main
Methode der Klasse TestPunkt
. Eine Ausnahme ist hier aber die Verwendung von this.x
bzw. this.y
anstelle von meinPunkt.x
bzw. meinPunkt.y
.
Was bedeutet also dieses this
? Übersetzt heißt this
dieses. Die Idee dahinter ist, dass wir ja nun innerhalb unserer Klasse Punkt
kein Objekt mit dem Namen meinPunkt
mehr haben, so wie es im Beispiel zuvor der Fall war. Wir möchten aber dennoch die Werte des aktuellen Objektes ausgeben. Die Verwendung von this.x
heißt also nichts anderes als diesesObjekt.x. Wir wollen von diesem Objekt das x bzw. y Attribut haben. Mit this
ist somit die Referenz auf das eigene Objekt gemeint. Hierzu lernen Sie später in diesem Kapitel mehr.
Ändern wir also nun unsere Klasse TestPunkt
, um die neue Klasse Punkt
zu testen.
public class TestPunkt { public static void main(String [] args) { Punkt meinPunkt = new Punkt(); meinPunkt.ausgabe(); } }
Wie im Beispiel zu den Attributen wird ein neues Objekt namens meinPunkt
angelegt.
Punkt meinPunkt = new Punkt();
Danach geben wir aber nicht die einzelnen Attribute dieses Objektes aus, sondern verwenden stattdessen die zugehörige Objektmethode ausgabe
.
meinPunkt.ausgabe();
Sie sehen hieran auch, dass der Zugriff auf Methoden ebenso über einen Punkt (.) funktioniert, wie wir es schon bei den Attributen gelernt haben.
Auf der Konsole erscheint folgender Text:
x-Wert: 10
y-Wert: 20
Wie Sie vielleicht feststellen werden, ist unser Punktobjekt noch recht statisch. Es hat immer die Werte „10“ für den x-Wert und „20“ für den y-Wert.
Anfangs wurde gesagt, dass eine Methode auch eine optionale Parameterliste haben kann. Dies wollen wir uns zu Nutze machen.
public class Punkt { private int x = 10; private int y = 20; public void setX(int neuesX) { this.x = neuesX; } public void setY(int neuesY) { this.y = neuesY; } public void ausgabe() { System.out.println("x-Wert: " + this.x); System.out.println("y-Wert: " + this.y); } }
Dazu wurde die Klasse Punkt
um zwei neue Methoden (setX
und setY
) erweitert. Im Vergleich zu der Methode ausgabe
enthalten diese beiden Methoden nun einen sogenannten Parameter.
int neuesX
bzw.
int neuesY
Diese Parameter sind vom Typ int
und tragen den Namen neuesX
bzw. neuesY
. Im Methodenrumpf wird dieser Parameter dazu verwendet den Wert der Attribute x
und y
neu zu setzen. Dies dürfte Ihnen bekannt vorkommen, da der Wert von Variablen ebenso mit einem Gleichheitszeichen geändert werden konnte (siehe Kapitel 02.02 Variablen Deklaration).
Das Attribut x
dieses Objektes – erinnern Sie sich an die Verwendung von this
– bekommt also nun den Wert, welchen der Parameter neuesX
enthält. Analog dazu verhält es sich mit dem Attribut y
in der Methode setY
. Es werden somit die Initialwerte „10“ und „20“ mit den neuen Werten überschrieben.
Um dieses neue Verhalten zu testen und zu veranschaulichen, ändern wir dementsprechend unsere Klasse TestPunkt
ab.
public class TestPunkt { public static void main(String [] args) { Punkt meinPunkt = new Punkt(); meinPunkt.setX(50); meinPunkt.setY(25); meinPunkt.ausgabe(); } }
An der Ausgabe dieses Programms sehen Sie, dass wir die Werte unseres Objektes meinPunkt
erfolgreich ändern konnten.
x-Wert: 50
y-Wert: 25
Es gibt noch eine andere Variante um Methoden zu verwenden. Es ist nämlich ebenso möglich sich einen Rückgabewert liefern zu lassen. Bisher hatten unsere Methoden immer ein void
(eng. Die Leere) als Rückgabe. Das bedeutet, unsere Methoden haben uns kein Ergebnis zurück geliefert. Um diese Möglichkeit nun ebenfalls zu implementieren erweitern wir wieder unsere Klasse Punkt
.
public class Punkt { private int x = 10; private int y = 20; public void setX(int neuesX) { this.x = neuesX; } public void setY(int neuesY) { this.y = neuesY; } public int getX() { return this.x; } public int getY() { return this.y; } public void ausgabe() { System.out.println("x-Wert: " + this.x); System.out.println("y-Wert: " + this.y); } }
Die neuen Methoden getX
und getY
sollen uns immer die aktuellen Werte der Attribute x
und y
zurückliefern. Dazu erhalten sie an Stelle des leeren Rückgabetyps void
den Typ unserer Rückgabe. Da die Attribute x
und y
vom Typ int
sind, ist das Ergebnis unserer Rückgabe ebenfalls vom Typ int
.
public int getX()
Die Rückgabe selbst erfolgt mit dem reservierten Wort return
. Wir wollen also dieses x zurück geben.
return this.x;
Dies testen wir nun wieder in unserer Klasse TestPunkt
.
public class TestPunkt { public static void main(String [] args) { Punkt meinPunkt = new Punkt(); meinPunkt.setX(50); meinPunkt.setY(25); System.out.println("x-Wert: " + meinPunkt.getX()); System.out.println("y-Wert: " + meinPunkt.getY()); } }
Hier wird wieder ein neues Objekt meinPunkt
erzeugt und die Werte „50“ und „25“ für x und y gesetzt. Bei der danach folgenden Ausgabe verwenden wir die neu implementierten Methoden getX
und getY
um an die Werte unserer Attribute zu gelangen.
meinPunkt.getX();
Als Ausgabe erhalten wir wieder:
x-Wert: 50
y-Wert: 25
Bei den hier vorgestellten Methoden setX
bzw. setY
und getX
bzw. getY
handelt es sich um sogenannte Setter– bzw. Getter-Methoden. Diese erlauben den Zugriff auf ein Objektattribut, ohne das man direkt auf dieses Attribut von Außerhalb zugreifen muss. In unserem Beispiel zu den Attributen haben wir noch direkt auf die Objektattribute zugegriffen und ihnen Werte zugewiesen. Dies kann aber unschöne Nebeneffekte mit sich bringen. Im Moment reicht es, wenn Sie wissen, dass man lieber über Setter-/Getter-Methoden auf Attribute zugreift, als den Weg des direkten Zugriffes zu wählen. Die Erklärungen hierzu finden Sie im Kapitel 04.03.06 Sichtbarkeitsmodifizierer. Zusätzlich dazu ist es gute Praxis Methoden, welche den Zustand eines boolschen Wertes zurückgeben, mit dem Verb ist bzw. is zu beginnen.
private int[] myField = new int[0]; public boolean isEmpty() { return myField.length == 0; }
Auf der nächsten Seite erfahren Sie etwas über this, wie man Methoden überladen kann und wie man varargs verwendet.
Hi Stefan
Es würde die Lesbarkeit erhöhen wenn Referenzen auf die angegebenen Codelistings, die entsprechende Zeilennummer des Codes enthalten…
(dann muss man nicht erst lange suchen)
also statt
1. public int getX()
eben
14. public int getX()
Gruss Roland
Hi Roland,
danke für die Anmerkung/Kritik. Die Codeformatierung wird von einem externen Plugin übernommen. Da wir keinen Einfluss auf die Features haben und damit wir es ggf. leicht austauschen können (gab schon mal Probleme damit), verzichten wir auf solche „Spielereien“.
Gruß
Stefan