Universität Hamburg - Fachbereiche - Fachbereich Mathematik

Java-Kurs (3)

WiSe 01/02

Bodo Werner

Zurück zum Inhaltsverzeichnis.

3. Methoden und Verzweigungen

3.1 Methoden (Teil 1)

Das einfachste Java-Analogon zu dem mathematischen Begriff einer reellen Funktion wie 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:


 class 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
Zunächst wird die Methode 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.
Man achte darauf, wie im 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

3.2 Verzweigungen

if, if - else

Verzweigungen erlauben die bedingte Ausführung von Anweisungen und sind damit unerlässlich für die Steuerung von Programmabläufen.

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:


static 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 
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 einer 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:


//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 
Die Syntax einer 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.

3.3 Methoden (Teil 2)

Da Methoden ein zentraler Begriff auch des OOP ist, soll der erste Umgang mit ihnen sicherer werden.

Zunächst ein Beispiel für eine Methode mit zwei Parametern und einem Rückgabewert - sämtlichst vom Typ int:


    //Methode3
    static int modulo(int m, int n){
	int M=m;
	while (M>=n) M-=n;
	return M;
    }//Ende modulo
 
Diese Methode 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:


    static void  schreibe(String s){
	System.out.println(s);
    }//Ende schreibe()
 
Im nächsten Abschnitt werden die Datentypen String und array behandelt.

Weiter mit Zeichenketter und Felder.