f(x)=sin(x)
oder
f(x)=x^3-x+3
ist das einer Methode mit Parameter (entspricht dem Argument
x
der Funktion) und mit Rückgabewert (entspricht dem Funktionswert
f(x)
) vom Typ double
.
Nehmen wir an, wir wollen eine Wertetabelle für die Funktion
f(x)=sin(2x)+cos(x)
anlegen. Dann muss f(x)
wiederholt ausgewertet werden. Dabei wird die Abbildungsvorschrift nur einmal
separat abgespeichert - als Methode:
static double f(double x){ return Math.sin(2*x)+Math.cos(x); }//Ende des Methodenblocks
f
ist der Bezeichner der Methode, x
der
Parameter. Das erste double
kenzeichnet den Typ des
Rückgabewertes. Mit return wird der
Rückgabewert der Methode "retourniert". Man achte auf die
geschweiften Klammern des Methodenblocks.
Ein Javaprogramm, das eine Wertetabelle mit Hilfe eines Aufrufs dieser Methode erstellt, kann so aussehen:
Zunächst wird die Methodeclass Methode1{ static double f(double x){ return Math.sin(2*x)+Math.cos(x); }//Ende des Methodenblocks static void main(String[] args){ double x=0; while (x<1) { System.out.println( "x="+x+" f(x)="+f(x)); x+=0.1; }//Ende while }//Ende main() }//Ende class Methode1
f
vereinbart. Der Zusatz (Modifier) static
muss wie bei der
Methode main()
stehen, weil es
sich um eine Klasse handelt, von der keine Instanz gebildet werden
soll, also um eine reine Applikationsklasse. Verstehen kann man dies
erst, wenn mit Objekten gearbeitet wird.
main()
-Block die Methode zur
Auswertung der Funktion aufgerufen wird: genauso, wie man es intuitiv
machen würde.
In obigem Beispiel war x sowohl ein Bezeichner für den Parameter der Methode f als auch für die Variable im main-Block, die als Parameter in f eingesetzt wird. Das muss nicht sein:
class Methode1a{ static double f(double x){ return Math.sin(2*x)+Math.cos(x); }//Ende des Methodenblocks static void main(String[] args){ double y=0; while (y<1) { System.out.println( "x="+y+" f(x)="+f(y)); y+=0.1; }//Ende while }//Ende main() }//Ende class Methode1a
Reelle Funktionen haben zuweilen einen eingeschränkten Definitionsbereich. So muss bei der Wurzelfunktion das Argument nichtnegativ sein, bei rationalen Funktionen darf der Nenner nicht verschwinden. Dies kann im Methodenblock realisiert werden:
Der if-Block umfasst mehr als eine Anweisung und muss daher durch geschweifte Klammern eingeschlossen werden. Bei nur einer Anweisung können diese Klammern fehlen. Die Syntax einerstatic double f(double x){ double y; //wird durch y=0 initialisiert if ((x>=0) & (x!=4)){ y= 1/(Math.sqrt(x)-2); }//Ende des if-Blocks return y; //Muss ausserhalb des if-Blocks stehen }//Ende des Methodenblocks
if
-Verzweigung lautet if (A)
B
. Dabei ist A ein Boole'scher Ausdruck und
B ist ein Block von Anweisungen. Wenn A false
ist, bewirkt die if
-Verzweigung gar nichts.
Der Compiler achtet bei einer Methode mit Rückgabewert streng darauf, dass in jedem Fall ein Wert
zurückgegeben wird. Wenn die return y
-Zeile in den
if
-Block wechselt, hat dies eine Fehlermeldung bei der
Compilierung zur Folge. Unsere Methode hat den offensichtlichen
Nachteil, dass der Wert y=0
zurückgegeben wird, wenn
x=4
oder x<0
. Mit einem
else-Zusatz wird dies anders (s.u.).
Allgemein dienen Verzweigungen dazu, bestimmte Programmteile beim Eintreten gewisser Bedingungen, die erst zur Laufzeit bekannt sind, ausführen zu lassen. In Ergänzung mit else kann die Verzweigung variabler gehandhabt werden:
Die Syntax einer//Methode2 static double f(double x){ if ((x>=0) & (x!=4)){ double y= 1/(Math.sqrt(x)-2); return y; }//Ende des if-Blocks else { System.out.println( "x="+x+" ist nicht im Definitionsbereich"); return Double.NaN; }//Ende else-Block }//Ende des Methodenblocks
if-else
-Anweisung lautet: if (A)
B else C
. Dabei sind B und C Blöcke von Anweisungen.
Ohne den return
-Befehl in vorletzten Zeile
hätte es den Compilerfehler Return required at end
of double f(double)
gegeben. Doch was soll
zurückgegeben werden, wenn der Parameter x
nicht im
Definitionsbereich der Funktion f
ist? Zum Glück
kennt Java die Konstante Double.NaN,
wobei NaN für Not a
Number steht und die als
double
-Rückgabewert akzeptiert wird.
Will man mehrere verschiedene Fälle abarbeiten (Mehrfachverzweigung), sollte man switch verwenden. Das soll hier aber nicht besprochen werden.
Zunächst ein Beispiel für eine Methode mit zwei Parametern
und einem Rückgabewert - sämtlichst vom Typ
int
:
Diese Methode//Methode3 static int modulo(int m, int n){ int M=m; while (M>=n) M-=n; return M; }//Ende modulo
modulo
berechnet m modulo n (das ist
der
Rest der Division von m
durch n
). So, wie
die Methode hier programmiert wurde, müssen beide Argumente positiv
sein, um eine
Endlosschleife zu vermeiden. Java hat hierfür einen eigenen arithmetischen Operator
% vorgesehen, so dass es einer Programmierung wie der obigen
nicht bedarf.
Es gibt auch Methoden ohne Rückgabewert wie die Methode
main()
. Diese müssen den Zusatz
void tragen. Ein weiters Beispiel einer Methode ohne
Rückgabewert ist die Methode
System.out.println()
. Diese könnte man durch die
folgende Methode etwas kürzer mit schreibe()
fassen,
wenn man Schreibarbeit an der Tastatur
sparen will:
Im nächsten Abschnitt werden die Datentypenstatic void schreibe(String s){ System.out.println(s); }//Ende schreibe()
String
und array
behandelt.