jario_
Wróć do przeglądu

Rozdział 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)
  1. public static: steht vorerst immer davor. Was es bedeutet, kommt in Kapitel 7.
  2. Rückgabetyp: double, int, boolean, String, … oder void, wenn die Methode nichts zurückgibt.
  3. Name: klein geschrieben, sagt, was die Methode tut.
  4. 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) ist 1,
  • 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));
        }
    }
}

Typowe błędy

  • Methode in main geschrieben

    Eine Methode darf nicht in einer anderen stehen. Steht sie zwischen den Klammern von main, meldet der Compiler illegal 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 return enden:

    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 sie return hat.

  • Parameter sind Kopien

    Bei int, double und boolean bekommt 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 StackOverflowError abbricht. Prüfe: Wird der Wert bei jedem Aufruf kleiner, und landet er sicher im Abbruchfall?