Kapitel 6
Methoden und Rekursion
In den letzten Kapiteln stand die Methode, die du ausfüllen solltest, schon im Starter-Code. Jetzt schreibst du sie selbst. Eine Methode gibt einem Stück Code einen Namen. Du rufst sie auf, so oft du willst, und musst den Code nur einmal schreiben.
Eigene Methoden
Eine Methode steht in der Klasse neben main, nicht darin. Ihr Kopf hat vier Teile:
public static double grossPrice(double net)
public static: steht vorerst immer davor. Was es bedeutet, kommt in Kapitel 7.- Rückgabetyp:
double,int,boolean,String, … odervoid, wenn die Methode nichts zurückgibt. - Name: klein geschrieben, sagt, was die Methode tut.
- Parameter: in Klammern, jeder mit Typ, getrennt durch Kommas. Beim Aufruf bekommen sie die Werte, die du übergibst.
return gibt das Ergebnis zurück und beendet die Methode sofort. Den Rückgabewert kannst du speichern, ausgeben oder weiterrechnen.
public class Main {
public static double grossPrice(double net) {
return net * 1.19;
}
public static boolean isAdult(int age) {
return age >= 18;
}
public static void printLine(int length) {
for (int i = 0; i < length; i++) {
System.out.print("-");
}
System.out.println();
}
public static void main(String[] args) {
printLine(20);
System.out.printf("Gross: %.2f%n", grossPrice(50.0));
double total = grossPrice(10.0) + grossPrice(20.0);
System.out.printf("Total: %.2f%n", total);
System.out.println("Adult at 17? " + isAdult(17));
printLine(20);
}
}Überladen und varargs
Mehrere Methoden dürfen gleich heißen, wenn sich ihre Parameter unterscheiden, in Anzahl oder Typ. Das heißt Überladen. Java sucht beim Aufruf anhand der Argumente die passende aus. Eine Methode darf dabei auch eine andere aufrufen, so wie max mit drei Parametern die mit zwei benutzt.
Soll eine Methode beliebig viele Werte bekommen, schreibst du drei Punkte hinter den Typ: int... numbers. Das heißt varargs. In der Methode ist numbers ein ganz normales Array, auch ein leeres, wenn du nichts übergibst.
public class Main {
public static int max(int a, int b) {
if (a > b) {
return a;
}
return b;
}
public static int max(int a, int b, int c) {
return max(max(a, b), c);
}
public static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}
public static void main(String[] args) {
System.out.println(max(3, 7));
System.out.println(max(3, 9, 5));
System.out.println(sum());
System.out.println(sum(4));
System.out.println(sum(1, 2, 3, 4));
}
}Rekursion
Eine Methode darf sich selbst aufrufen. Das heißt Rekursion und passt, wenn sich ein Problem auf eine kleinere Version desselben Problems zurückführen lässt. Jede Rekursion braucht zwei Teile:
- einen Abbruchfall, der das Ergebnis direkt kennt, z. B.
factorial(1)ist1, - einen rekursiven Aufruf mit einem kleineren Wert, z. B.
n * factorial(n - 1).
So rechnet Java factorial(3): 3 * factorial(2) → 3 * 2 * factorial(1) → 3 * 2 * 1 = 6.
public class Main {
public static void countdown(int n) {
if (n == 0) {
System.out.println("Go!");
return;
}
System.out.println(n);
countdown(n - 1);
}
public static int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
countdown(3);
for (int i = 1; i <= 5; i++) {
System.out.println(i + "! = " + factorial(i));
}
}
}Typische Fehler
Methode in main geschrieben
Eine Methode darf nicht in einer anderen stehen. Steht sie zwischen den Klammern von
main, meldet der Compilerillegal start of expression. Methoden stehen nebeneinander in der Klasse.return fehlt in einem Zweig
Hat eine Methode einen Rückgabetyp, muss jeder Weg durch sie mit
returnenden:public static String sign(int n) { if (n > 0) { return "positive"; } else if (n < 0) { return "negative"; } // missing return statement }Ein
return "zero";am Ende behebt den Fehler.Rückgabewert verworfen
grossPrice(10.0);allein rechnet zwar, aber das Ergebnis geht verloren. Speichere es (double price = grossPrice(10.0);) oder gib es aus. Umgekehrt druckt eine Methode nichts, nur weil siereturnhat.Parameter sind Kopien
Bei
int,doubleundbooleanbekommt die Methode eine Kopie des Werts. Ändert sie den Parameter, merkt der Aufrufer nichts davon. Bei Arrays bekommt sie dagegen den Verweis auf dasselbe Array (siehe Kapitel 4): Änderungen an den Elementen sind danach auch außerhalb sichtbar.Rekursion ohne Abbruch
Fehlt der Abbruchfall oder wird er nie erreicht, ruft sich die Methode immer weiter auf, bis das Programm mit
StackOverflowErrorabbricht. Prüfe: Wird der Wert bei jedem Aufruf kleiner, und landet er sicher im Abbruchfall?