In Java spielen Methoden eine zentrale Rolle. Sie bestimmen das Verhalten von Objekten und somit auch das Verhalten des gesamten Programms.
Methoden arbeiten in Java immer mit den Daten (Variablen) von Objekten. Das unterscheidet sie von Funktionen, die man in anderen Programmiersprachen vorfinden kann und welche vollkommen unabhängig von einem Objekt oder einer Klasse existieren. Funktionen sind in Java nicht implementiert.
In diesem Beitrag möchten wir uns den vier Themen widmen:
- Methodendefinition
- Aufrufen von Methoden
- Parameterliste
- Rückgabewert von Methoden
In den beiden weiterführenden Beiträgen werden wir die fortgeschrittenen Themen zu Methoden in Java: variable Parameterliste und Überladen von Methoden behandeln.
Methodendefinition – Definieren von Methoden in Java
Die Methodendefinition wird innerhalb der Klassendefinition vorgenommen. Die Methoden haben dadurch Zugriff auf alle Variablen des Objekts.
Die Syntax der Methodendefinition in Java ist sehr einfach:
Modifier Datentyp Methodenname (Parameterliste) { Anweisungen; }
In der Methodendefinition können mehrere Modifier angegeben werden. Wir werden Modifier in einem späteren Beitrag vorstellen.
An zweiter Stelle steht der Datentyp des Rückgabewerts der Methode. Diesem folgt der Methodenname und ein Klammernpaar, in dem sich die optionale Parameterliste befindet. Das Klammernpaar muss in jedem Fall angegeben werden, auch wenn eine leere Parameterliste verwendet wird.
Die Anweisungen, welche das Verhalten der Methode vorgeben, stehen im Methodenrumpf innerhalb der beiden geschweiften Klammern.
In dem folgenden Quellcode-Beispiel wird die Klasse Schaf um die sehr einfache Methode berechneVerkaufspreis erweitert:
Syntax: Klasse Schaf mit der Methode berechneVerkaufspreis.
public class Schaf { public String name; public byte alter; public float wollMenge; public float berechneVerkaufspreis() { int quadratmeterpreis = 15; return (wollMenge * quadratmeterpreis); } }
Die oben angegebene Methode berechneVerkaufspreis gibt den berechneten Wert als float-Datentyp zurück. Eine Parameterliste wird für die Berechnung nicht benötigt, da die Methode direkt auf die Variablen des Objekts zugreifen kann.
Methodenaufruf – Aufrufen von Methoden in Java
Methoden werden in Java mittels Punktnotation aufgerufen.
Dies erfolgt auf die gleiche Art und Weise wie der Zugriff auf Instanzvariablen, nur müssen bei Methodenaufrufen zusätzlich die Parameter der Methode in Klammern angegeben werden.
Besitzt die aufzurufende Methode nur eine leere Parameterliste, muss ein leeres Klammernpaar an den Methodennamen angehängt werden.
Die Syntax für Methodenaufrufe in Java ist wie folgt:
meinObjekt.methodeA(); // ohne Parameterliste meinObjekt.methodeB(param1, param2); // mit Parameterliste
In Java können Methoden auf die Instanzvariablen ihrer Klassen zugreifen ohne dabei die Punktnotation zu benötigen.
Diese kürzere Schreibweise wird durch den Java-Compiler ermöglicht, der vor alle nichtlokal verwendeten Variablen das this-Objekt setzt.
Die beiden folgenden Methodendefinitionen bewirken beide das gleiche Programmverhalten:
public float berechneVerkaufspreis1() { int quadratmeterpreis = 15; return (wollMenge * quadratmeterpreis); } public float berechneVerkaufspreis2() { int quadratmeterpreis = 15; return (this.wollMenge * quadratmeterpreis); }
Das Schlüsselwort this repräsentiert eine Referenzvariable, die auf das aktuelle Objekt verweist. Die this-Referenzvariable wird beim Anlegen eines Objekts automatisch erzeugt.
Mit this wird auf die eigenen Methoden und Instanzvariablen des Objekts zugegriffen. Wie in dem oberen Quellcode-Beispiel angegeben, kann die this-Referenzvariable auch explizit (this.wollMenge
) verwendet werden, so wie eine ganz normale Objektvariable.
Die this-Referenzvariable wird an alle nichtstatischen Methoden als versteckter Parameter übergeben.
Möchte man besonders hervorheben, dass auf eine Instanzvariable zugegriffen wird und nicht auf eine lokale Variable der Methode, dann bietet es sich an die this-Referenzvariable explizit zu verwenden, auch wenn dies nicht unbedingt erforderlich wäre.
Parameterliste – Methodenparameter in Java definieren
Einer Methode können Daten übergeben werden, mit denen sie dann arbeiten kann. Welche Daten übergeben werden können, wird von der Parameterliste der Methodendefinition vorgegeben.
Die Parameterliste wird innerhalb der Klammern direkt nach dem Methodennamen angegeben. Sie kann aus beliebig vielen Parametern bestehen. Jeder dieser Parameter besitzt einen Datentyp- und Parameternamen. Die einzelnen Parameter werden durch Kommas voneinander getrennt.
In folgendem Beispiel sind vier Methodenköpfe mit verschiedenen Parameterlisten angegeben:
public double methodeA(); // Methode mit leerer Parameterliste public double methodeB(int a); // Parameterliste mit einem primitiven Parameter public double methodeC(String a); // Parameterliste mit einem Objekttyp-Parameter public double methodeD(int a, int b); // Parameterliste mit zwei Parametern
Die Parameterliste kann auch primitive Parameter und Objektparameter vermischen. Wie wir in einem weiterführenden Beitrag sehen werden, bekommt jede Methode eine einzigartige Signatur zugewiesen, für die sogar die Reihenfolge der Parameter ausgewertet wird.
Call by Value – Der Wert wird in die Parametervariable kopiert
In Java wird bei einem Methodenaufruf der zu übergebende Wert in die Parametervariable der Methode kopiert und auf diese Weise an die Methode übergeben.
Diese Variante der Wertübergabe wird als „call by value“ bezeichnet.
Da innerhalb der Methode nur mit dem kopierten Wert gearbeitet wird, bleiben Veränderungen an der Parametervariable lokal und haben keine Auswirkungen auf den Aufrufer.
Die folgende Beispielanwendung gibt einen Zählerstand auf der Kommandozeile aus:
Beispielanwendung eines Zählers (Call by Value).
/* * Beispielanwendung eines Zählers (Call by Value) */ public class CounterExample { int counter = 10; public void countdown(int param) { System.out.println(); while(param >= 0) { System.out.println("Counter: " + param); param = param - 1; } } public static void main(String[] args) { CounterExample meinObjekt = new CounterExample(); meinObjekt.countdown(meinObjekt.counter); meinObjekt.countdown(meinObjekt.counter); meinObjekt.countdown(meinObjekt.counter); } }
Zunächst wird die Instanzvariable counter deklariert und mit dem Wert 10 initialisiert. Anschließend werden die Methoden countdown und main definiert.
In der Methode main wird die Methode countdown dreimal über das CounterExample-Objekt meinObjekt aufgerufen und ihr dabei jeweils der Wert der Instanzvariable counter übergeben. Bei dem Aufrufen der Methode countdown wird der in counter gespeicherte Wert kopiert und in der Parametervariable param gespeichert.
In der Methode countdown wird dann der Wert von param bei jedem Schleifendurchlauf ausgegeben und um 1 reduziert. Die Schleife wird beendet, sobald param kleiner als 0 ist.
Obwohl der Methodenparameter param in der Methode verändert wird, hat dies keine Auswirkungen auf die Instanzvariable counter. Der Aufrufer merkt von den Vorgängen innerhalb der Methode nichts, da die Methode nur mit einer Kopie des Inhalts von counter arbeitet.
Starten wir nun die Anwendung. In der folgenden Abbildung ist die Kommandozeilenausgabe der Beispielanwendung darstellt:
Call by Reference – Die Referenz wird in die Parametervariable kopiert
Bei Referenzvariablen, also Variablen die auf ein Objekt verweisen, muss folgende Besonderheit beim Übergeben der Referenzvariable an die Methode unbedingt beachtet werden.
Bei der Übergabe der Referenzvariable an die Methode wird die Referenz (der Verweis auf das Objekt) kopiert und in der Parametervariable der Methode gespeichert.
Innerhalb der Methode wird nun mit einer Kopie der Referenz gearbeitet, dadurch erfolgt der Zugriff direkt auf das Originalobjekt und Veränderungen wirken sich immer auf das Originalobjekt aus und sind für den Aufrufer sichtbar.
Diese Variante der Wertübergabe wird als „call by reference“ bezeichnet.
Werden Objekte an Methoden übergeben, dann erhält die Methode keine Kopie des Objekts, sondern die Referenz auf das Originalobjekt. Um genau zu sein: Die Methode erhält eine Kopie der Referenz.
Da nur die Kopie der Referenz und nicht das Objekt selbst übergeben wird, ist die Übergabe von Objekten in Java sehr performant. Die Größe der Objekte spielt dabei keine Rolle.
Soll in besonderen Fällen mit einer Kopie des Objekts gearbeitet werden, dann muss vorher das Originalobjekt explizit durch die Methode clone der Object-Klasse kopiert bzw. gecloned werden.
Hinweis: Call by Reference kann zu verdeckten Fehlern führen. Werden Objekte (inkl. Arrays) an eine Methode übergeben, dann arbeitet die Methode immer mit den Originalobjekten und kann somit deren Instanzvariablen und bei Arrays deren Elemente verändern. Um dies zu verhindern, muss vorher das Originalobjekt mit der Methode clone kopiert und anschließend nur mit dieser Kopie gearbeitet werden.
Rückgabewert – Zurückliefern eines Werts aus der Methode heraus
In der Methodendefinition wird der Datentyp des Rückgabewerts festgelegt. Der Datentyp wird direkt vor dem Methodennamen angegeben, siehe folgendes Beispiel:
public int methodeA(); // Datentyp des Rückgabewerts ist int public String methodeB(); // Datentyp des Rückgabewerts ist String public void methodeC(); // Kein Rückgabewert da void (leer)
Der Rückgabewert einer Methode kann von einem primitiven Datentyp oder Objekttyp sein. Es ist auch möglich, dass die Methode gar keinen Rückgabewert zurückliefert. In diesem Fall ist die Methode vom Typ void und darf nur als Ausdrucksanweisung eingesetzt werden.
Der Rückgabewert wird mit Hilfe der return-Anweisung an den Aufrufer übergeben.
Nachdem die return-Anweisung ausgeführt wurde, wird die Methode beendet und verlassen. Anweisungen, die nach der return-Anweisung im Quellcode stehen, werden nicht mehr ausgeführt und sind daher nicht erreichbar.
Wird ein Rückgabewert an den Aufrufer zurückgegeben, so muss sichergestellt werden, dass der Datentyp des Rückgabewerts zuweisungskompatibel ist. Somit muss die Variable, die den Rückgabewert aufnehmen soll, auch kompatibel zu dem Datentyp des zurückgelieferten Werts sein.
Comments 2
Daaaaaankkeeeeee
Pingback: Klassen in Java: Die Grundlagen der objektorientierten Programmierung