Methode: Unterschied zwischen den Versionen
Hauer (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „= Syntaxdiagramm = Datei:method_declaration.png“) |
|||
(38 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
+ | Eine '''Methode''' definiert ein (Teil-)Programm oder Unterprogramm. | ||
+ | |||
+ | =Unterscheidung Methode und Funktion= | ||
+ | |||
+ | Üblicherweise wird eine Methode von einer '''Funktion''' unterschieden: Eine Methode wird auf einem [[Objekt]] ausgeführt, eine Funktion wird nach Belieben aufgerufen. Bei der Deklaration unterscheidet man zwischen Methode und Funktion nur durch den [[Modifikator]] [[static]]. | ||
+ | |||
+ | Eine Funktion wird im '''statischen Kontext''' der [[Klasse]] ausgeführt und hat daher nur Zugriff auf Klassenattribute und lokale Variablen, während eine Methode zusätzlich Zugriff auf Attribute der '''Objektinstanz''' hat. | ||
+ | |||
= Syntaxdiagramm = | = Syntaxdiagramm = | ||
[[Datei:method_declaration.png]] | [[Datei:method_declaration.png]] | ||
+ | |||
+ | = Deklaration = | ||
+ | |||
+ | ==Erläuterung== | ||
+ | |||
+ | Eine (statische) Methode wird innerhalb des Klassenrumpfes mit Angabe der [[Modifikator]]en (''visibility'' und ''functional modifier''), des [[Rückgabe]][[Datentyp|typs]] (''primitive type'' oder ''identifier'') und des Namens (''identifier'') deklariert. Darauf folgen in runden Klammern die Parameter. Danach kommt der eigentliche Rumpf der Methode innerhalb von geschweiften Klammern in Form eines [[Block | Blocks]]. | ||
+ | |||
+ | Wird der Modifikator [[abstract]] verwendet, so wird nur die [[Signatur]] der Methode, nicht aber ihr Rumpf angegeben. Die Deklaration wird mit einem Semikolon abgeschlossen. | ||
+ | |||
+ | == Beispiele == | ||
+ | |||
+ | <source lang="java" title="Beispiel 1"> | ||
+ | private static int foo(int bar){ | ||
+ | // ... // | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Dies ist eine [[privat]]e, [[statisch]]e Methode, die einen [[int]] berechnet, [[foo]] heißt und einen '''int''' namens [[bar]] als Parameter erwartet. Die Methode benötigt eine Implementierung, die hier aber nicht weiter relevant ist. | ||
+ | |||
+ | <source lang="java" title="Beispiel 2"> | ||
+ | public abstract double bar(double foo); | ||
+ | </source> | ||
+ | |||
+ | Dies ist eine [[öffentlich]]e, [[abstrakt]]e Methode, die einen [[double]] berechnet, '''bar''' heißt und einen '''double''' namens '''foo''' als Parameter erwartet. Dem Methodenkopf folgt keine Implementierung, da sie als abstrakt deklariert ist und von einer [[Vererbung | erbenden Klasse]] implementiert werden soll. | ||
+ | |||
+ | = Parameter = | ||
+ | |||
+ | Die '''Parameter''' einer Methode sind [[Variable]]n, deren Werte beim '''Aufruf''' der Methode festgelegt werden. Ein '''Parameter''' ist daher immer mit einem Wert initialisiert. Methoden haben nur Zugriff auf Variablen, die für sie sichtbar sind: Dies sind zu Beginn des Aufrufs nur die '''Parameter''' der Methode und gegebenenfalls Attribute des Objektes, auf dem die Methode aufgerufen wurde. Die Parameter der Methode gehören daher zu den [[Variable#Lokale Variable|lokalen Variablen]] der Methode. Die '''Übergabe von Parametern''' geschieht per [[Call by Value]] bei [[primitiver Datentyp | primitiven Datentypen]] und per [[Call by Reference]] bei Objekten. | ||
+ | |||
+ | = Organisation = | ||
+ | |||
+ | Funktionen und Methoden werden hauptsächlich deklariert, um den Quellcode zu strukturieren. Es bietet sich immer an, häufig verwendete Codefragmente als eigene Funktion auszulagern. | ||
+ | |||
+ | Die Funktionalität eines Objektes sollte durch seine verfügbaren Methoden repräsentiert werden. Diese Funktionalitäten sollten relativ einfach formulierbar sein (frei nach dem Motto "Do one thing, and do it well!"<ref>Unix Philosophy</ref>). Meistens beinhalten diese insbesondere die Fähigkeit, Attribute des Objektes zu manipulieren oder in Abhängigkeit von diesen spezielle Aufgaben zu erfüllen. | ||
+ | |||
+ | = Statisch vs. nicht statisch = | ||
+ | |||
+ | Ein [[Java]]-Programm beginnt immer in der [[main]]-Methode im '''statischen''' Kontext. Das heißt die Ausführung des Programms findet nicht innerhalb einer Instanz eines [[Objekt|Objektes]] statt. | ||
+ | |||
+ | Wird auf einem Objekt eine Methode ausgeführt, wechselt das Programm in einen '''nicht statischen''' Kontext, in dem die Ausführung des Programms abhängig vom Zustand des Objektes ist, auf dem die Methode ausgeführt wird. | ||
+ | |||
+ | Innerhalb einer Klasse selbst können aus einem statischen Kontext heraus keine nicht-statischen Methoden aufgerufen oder nicht-statische Attribute manipuliert werden; es ist kein Objekt vorhanden, dass dies machen könnte. Möchte man es trotzdem tun, so muss man aus dem statischen Kontext heraus eine Objektinstanz erstellen und auf dem erstellen Objekt die gewünschte Methode aufrufen. In den meisten Fällen ergibt das jedoch für den Ablauf des Programms keinen Sinn. | ||
+ | |||
+ | In der '''Praxis''' möchte man in der [[Objektorientierte Programmierung|'''objektorientierten Programmierung''']] den Ablauf eines Programms so schnell wie möglich in einen an ein Objekt gebundenen, nicht-statischen Kontext überführen und, außer in Spezialfällen<ref>Verwendung von hilfreichen Funktionen, die keinen Objektzustand benötigen und keinen neuen erzeugen, wie z.B. mathematische Funktionen wie <code>cos</code>. Diese berechnen meist eine einfache Funktion und geben einen Wert zurück, ohne den Zustand des Programmes in irgendeiner Weise zu beeinflussen.</ref>, in diesem verbleiben. | ||
+ | |||
+ | = Rückgabe = | ||
+ | |||
+ | ==Erläuterung== | ||
+ | |||
+ | Der von einer Methode berechnete Wert wird als ihr '''zurückgegebener Wert''' oder '''Rückgabewert''' bezeichnet. Der Programmfluss kehrt sozusagen nach dem Aufruf der Methode mit ihrem Wert in die Programmzeile zurück, in der sie aufgerufen wurde. | ||
+ | |||
+ | Im Quellcode wird das '''Ergebnis''' der Berechnung mit dem [[Schlüsselwort]] '''return''' (engl. ''zurückgeben/zurückkehren'') gekennzeichnet. Hinter dem Schlüsselwort wird der Term notiert, der das Ergebnis beschreiben soll. | ||
+ | |||
+ | Egal auf welche Art und Weise eine Methode terminiert, als letzte Anweisung muss ein Wert zurückgegeben werden. Das heißt, die letzte Anweisung muss immer ein '''return''' sein. Ansonsten ist die Methode unvollständig und wird vom [[Compiler]] nicht akzeptiert. | ||
+ | |||
+ | Die einzige Ausnahme hierzu sind Methoden mit dem '''Rückgabetyp''' [[void]]. Sie werden auch häufig als '''Prozeduren''' bezeichnet. Prozeduren berechnen keine Ergebnisse und müssen daher auch keine Werte zurückgeben. Mit einem einzelnen '''return''' als Anweisung kann die Ausführung der Prozedur jedoch vor Erreichen der letzten Anweisung beendet werden und zum Aufrufer zurückkehren. | ||
+ | |||
+ | Ein Beispiel für eine Methode mit diesem Rückgabetyp ist die [[main]]-Methode. | ||
+ | |||
+ | == Beispiele == | ||
+ | |||
+ | <source lang="java" title="Normale Rückgabe"> | ||
+ | public int average(int x, int y){ | ||
+ | return (x + y) / 2; // Gibt das Ergebnis zurück. | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | |||
+ | <source lang="java" title="Vorzeitiger Abbruch"> | ||
+ | public void printIfPositive(int x){ | ||
+ | if(x < 0) return; // Bricht die Ausführung der Prozedur vorzeitig ab, wenn x kleiner 0 ist. | ||
+ | System.out.println(x); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == Negativbeispiel == | ||
+ | |||
+ | <source lang="java"> | ||
+ | /** | ||
+ | * Soll zwei Zahlen miteinander dividieren, | ||
+ | * solange der Nenner y ungleich 0 ist. | ||
+ | */ | ||
+ | public double div(int x, int y){ | ||
+ | if(y != 0) return (double) x / (double) y; | ||
+ | } | ||
+ | </source> | ||
+ | Hier liegt ein Syntaxfehler vor, da die Methode für den Fall ''y ist 0'' keinen Wert zurückgibt. | ||
+ | |||
+ | = Fußnoten = | ||
+ | <references /> |
Aktuelle Version vom 2. März 2017, 15:29 Uhr
Eine Methode definiert ein (Teil-)Programm oder Unterprogramm.
Inhaltsverzeichnis
Unterscheidung Methode und Funktion
Üblicherweise wird eine Methode von einer Funktion unterschieden: Eine Methode wird auf einem Objekt ausgeführt, eine Funktion wird nach Belieben aufgerufen. Bei der Deklaration unterscheidet man zwischen Methode und Funktion nur durch den Modifikator static.
Eine Funktion wird im statischen Kontext der Klasse ausgeführt und hat daher nur Zugriff auf Klassenattribute und lokale Variablen, während eine Methode zusätzlich Zugriff auf Attribute der Objektinstanz hat.
Syntaxdiagramm
Deklaration
Erläuterung
Eine (statische) Methode wird innerhalb des Klassenrumpfes mit Angabe der Modifikatoren (visibility und functional modifier), des Rückgabetyps (primitive type oder identifier) und des Namens (identifier) deklariert. Darauf folgen in runden Klammern die Parameter. Danach kommt der eigentliche Rumpf der Methode innerhalb von geschweiften Klammern in Form eines Blocks.
Wird der Modifikator abstract verwendet, so wird nur die Signatur der Methode, nicht aber ihr Rumpf angegeben. Die Deklaration wird mit einem Semikolon abgeschlossen.
Beispiele
private static int foo(int bar){ // ... // }
Dies ist eine private, statische Methode, die einen int berechnet, foo heißt und einen int namens bar als Parameter erwartet. Die Methode benötigt eine Implementierung, die hier aber nicht weiter relevant ist.
public abstract double bar(double foo);
Dies ist eine öffentliche, abstrakte Methode, die einen double berechnet, bar heißt und einen double namens foo als Parameter erwartet. Dem Methodenkopf folgt keine Implementierung, da sie als abstrakt deklariert ist und von einer erbenden Klasse implementiert werden soll.
Parameter
Die Parameter einer Methode sind Variablen, deren Werte beim Aufruf der Methode festgelegt werden. Ein Parameter ist daher immer mit einem Wert initialisiert. Methoden haben nur Zugriff auf Variablen, die für sie sichtbar sind: Dies sind zu Beginn des Aufrufs nur die Parameter der Methode und gegebenenfalls Attribute des Objektes, auf dem die Methode aufgerufen wurde. Die Parameter der Methode gehören daher zu den lokalen Variablen der Methode. Die Übergabe von Parametern geschieht per Call by Value bei primitiven Datentypen und per Call by Reference bei Objekten.
Organisation
Funktionen und Methoden werden hauptsächlich deklariert, um den Quellcode zu strukturieren. Es bietet sich immer an, häufig verwendete Codefragmente als eigene Funktion auszulagern.
Die Funktionalität eines Objektes sollte durch seine verfügbaren Methoden repräsentiert werden. Diese Funktionalitäten sollten relativ einfach formulierbar sein (frei nach dem Motto "Do one thing, and do it well!"[1]). Meistens beinhalten diese insbesondere die Fähigkeit, Attribute des Objektes zu manipulieren oder in Abhängigkeit von diesen spezielle Aufgaben zu erfüllen.
Statisch vs. nicht statisch
Ein Java-Programm beginnt immer in der main-Methode im statischen Kontext. Das heißt die Ausführung des Programms findet nicht innerhalb einer Instanz eines Objektes statt.
Wird auf einem Objekt eine Methode ausgeführt, wechselt das Programm in einen nicht statischen Kontext, in dem die Ausführung des Programms abhängig vom Zustand des Objektes ist, auf dem die Methode ausgeführt wird.
Innerhalb einer Klasse selbst können aus einem statischen Kontext heraus keine nicht-statischen Methoden aufgerufen oder nicht-statische Attribute manipuliert werden; es ist kein Objekt vorhanden, dass dies machen könnte. Möchte man es trotzdem tun, so muss man aus dem statischen Kontext heraus eine Objektinstanz erstellen und auf dem erstellen Objekt die gewünschte Methode aufrufen. In den meisten Fällen ergibt das jedoch für den Ablauf des Programms keinen Sinn.
In der Praxis möchte man in der objektorientierten Programmierung den Ablauf eines Programms so schnell wie möglich in einen an ein Objekt gebundenen, nicht-statischen Kontext überführen und, außer in Spezialfällen[2], in diesem verbleiben.
Rückgabe
Erläuterung
Der von einer Methode berechnete Wert wird als ihr zurückgegebener Wert oder Rückgabewert bezeichnet. Der Programmfluss kehrt sozusagen nach dem Aufruf der Methode mit ihrem Wert in die Programmzeile zurück, in der sie aufgerufen wurde.
Im Quellcode wird das Ergebnis der Berechnung mit dem Schlüsselwort return (engl. zurückgeben/zurückkehren) gekennzeichnet. Hinter dem Schlüsselwort wird der Term notiert, der das Ergebnis beschreiben soll.
Egal auf welche Art und Weise eine Methode terminiert, als letzte Anweisung muss ein Wert zurückgegeben werden. Das heißt, die letzte Anweisung muss immer ein return sein. Ansonsten ist die Methode unvollständig und wird vom Compiler nicht akzeptiert.
Die einzige Ausnahme hierzu sind Methoden mit dem Rückgabetyp void. Sie werden auch häufig als Prozeduren bezeichnet. Prozeduren berechnen keine Ergebnisse und müssen daher auch keine Werte zurückgeben. Mit einem einzelnen return als Anweisung kann die Ausführung der Prozedur jedoch vor Erreichen der letzten Anweisung beendet werden und zum Aufrufer zurückkehren.
Ein Beispiel für eine Methode mit diesem Rückgabetyp ist die main-Methode.
Beispiele
public int average(int x, int y){ return (x + y) / 2; // Gibt das Ergebnis zurück. }
public void printIfPositive(int x){ if(x < 0) return; // Bricht die Ausführung der Prozedur vorzeitig ab, wenn x kleiner 0 ist. System.out.println(x); }
Negativbeispiel
/** * Soll zwei Zahlen miteinander dividieren, * solange der Nenner y ungleich 0 ist. */ public double div(int x, int y){ if(y != 0) return (double) x / (double) y; }
Hier liegt ein Syntaxfehler vor, da die Methode für den Fall y ist 0 keinen Wert zurückgibt.
Fußnoten
- ↑ Unix Philosophy
- ↑ Verwendung von hilfreichen Funktionen, die keinen Objektzustand benötigen und keinen neuen erzeugen, wie z.B. mathematische Funktionen wie
cos
. Diese berechnen meist eine einfache Funktion und geben einen Wert zurück, ohne den Zustand des Programmes in irgendeiner Weise zu beeinflussen.