Zum Inhalt springen
Java Anfänger 20 min

Methoden-Überladung

Lerne Methoden-Überladung (Overloading) in Java: Mehrere Methoden mit gleichem Namen, aber verschiedenen Parametern. Mit praktischen Beispielen.

Aktualisiert:

Methoden-Ueberladung (Overloading)

Stell dir vor, du moechtest eine Methode addiere(), die sowohl zwei als auch drei Zahlen addieren kann, und die auch mit Dezimalzahlen funktioniert. In Java ist das moeglich — mit Methoden-Ueberladung (Overloading).

Was ist Methoden-Ueberladung?

Ueberladung bedeutet: Mehrere Methoden haben den gleichen Namen, aber unterschiedliche Parameter:

static int addiere(int a, int b) {
    return a + b;
}

static int addiere(int a, int b, int c) {
    return a + b + c;
}

static double addiere(double a, double b) {
    return a + b;
}

public static void main(String[] args) {
    System.out.println(addiere(5, 3));         // 8 (int, int)
    System.out.println(addiere(1, 2, 3));      // 6 (int, int, int)
    System.out.println(addiere(1.5, 2.7));     // 4.2 (double, double)
}

Java entscheidet anhand der Argumente, welche Methode aufgerufen wird.

Regeln fuer Ueberladung

Methoden duerfen ueberladen werden, wenn sie sich in mindestens einem dieser Punkte unterscheiden:

Darf sich unterscheidenBeispiel
Anzahl der Parameteradd(int a) vs. add(int a, int b)
Typen der Parameteradd(int a) vs. add(double a)
Reihenfolge der Typenlog(String s, int i) vs. log(int i, String s)

NICHT relevant fuer Ueberladung:

Zaehlt NICHTBeispiel
Rueckgabetypint add(int a) vs. double add(int a) — FEHLER!
Parameternamenadd(int x) vs. add(int y) — FEHLER!
Zugriffsmodifiziererpublic void m() vs. private void m() — FEHLER!
// FEHLER: Gleiche Signatur (nur Parametername anders)
// static int addiere(int zahl1, int zahl2) { ... }
// static int addiere(int a, int b) { ... }

// FEHLER: Gleiche Signatur (nur Rueckgabetyp anders)
// static int berechne(int x) { return x; }
// static double berechne(int x) { return x; }

Praktische Beispiele

Vielseitige println-Methode

System.out.println() ist selbst ein perfektes Beispiel fuer Ueberladung:

System.out.println();          // keine Parameter
System.out.println("Hallo");   // String
System.out.println(42);        // int
System.out.println(3.14);      // double
System.out.println(true);      // boolean
System.out.println('A');       // char

Eigene formatiere-Methode

static String formatiere(String text) {
    return "[" + text + "]";
}

static String formatiere(String text, int breite) {
    return String.format("%-" + breite + "s", text);
}

static String formatiere(String text, String prefix, String suffix) {
    return prefix + text + suffix;
}

public static void main(String[] args) {
    System.out.println(formatiere("Hallo"));           // [Hallo]
    System.out.println(formatiere("Hallo", 20));       // Hallo
    System.out.println(formatiere("Hallo", "<<", ">>")); // <<Hallo>>
}

Flexible Suche

static int finde(int[] array, int wert) {
    for (int i = 0; i < array.length; i++) {
        if (array[i] == wert) return i;
    }
    return -1;
}

static int finde(int[] array, int wert, int startIndex) {
    for (int i = startIndex; i < array.length; i++) {
        if (array[i] == wert) return i;
    }
    return -1;
}

static int finde(String[] array, String wert) {
    for (int i = 0; i < array.length; i++) {
        if (array[i].equals(wert)) return i;
    }
    return -1;
}

Konstruktor-Ueberladung (Vorschau)

Auch Konstruktoren koennen ueberladen werden — das lernen wir spaeter im Detail:

public class Rechteck {
    double breite;
    double hoehe;

    // Konstruktor mit zwei Parametern
    Rechteck(double breite, double hoehe) {
        this.breite = breite;
        this.hoehe = hoehe;
    }

    // Konstruktor fuer Quadrat (nur eine Seitenlaenge)
    Rechteck(double seite) {
        this(seite, seite); // Ruft den anderen Konstruktor auf
    }

    // Standard-Konstruktor
    Rechteck() {
        this(1.0, 1.0);
    }
}

Wie waehlt Java die richtige Methode?

Java folgt einem klaren Prozess:

1. Exakte Uebereinstimmung

static void test(int x) { System.out.println("int"); }
static void test(double x) { System.out.println("double"); }

test(42);    // "int" -- exakte Uebereinstimmung
test(3.14);  // "double" -- exakte Uebereinstimmung

2. Automatische Erweiterung (Widening)

static void test(long x) { System.out.println("long"); }
static void test(double x) { System.out.println("double"); }

test(42);    // "long" -- int wird zu long erweitert (naeher als double)

3. Autoboxing

static void test(Integer x) { System.out.println("Integer"); }

test(42);    // "Integer" -- int wird zu Integer geboxt

4. Varargs (niedrigste Prioritaet)

static void test(int x) { System.out.println("int"); }
static void test(int... x) { System.out.println("varargs"); }

test(42);        // "int" -- exakt hat Vorrang
test(1, 2, 3);   // "varargs"

Ueberladung vs. Ueberschreibung

Verwechsle diese Begriffe nicht:

AspektUeberladung (Overloading)Ueberschreibung (Overriding)
WasGleicher Name, andere ParameterGleicher Name, gleiche Parameter
WoIn derselben KlasseIn Unterklasse
Wann entschiedenBeim KompilierenZur Laufzeit
VererbungNicht noetigErfordert Vererbung

Ueberschreibung lernst du spaeter beim Thema Vererbung.

Vergleich mit Python

Python hat keine direkte Methoden-Ueberladung. Stattdessen nutzt man Standardwerte:

# Python: Standardwerte statt Ueberladung
def begruesse(name, gruss="Hallo"):
    print(f"{gruss} {name}!")

begruesse("Max")            # Hallo Max!
begruesse("Max", "Hi")      # Hi Max!
// Java: Ueberladung fuer verschiedene Varianten
static void begruesse(String name) {
    begruesse(name, "Hallo"); // Delegiert an die andere Methode
}

static void begruesse(String name, String gruss) {
    System.out.println(gruss + " " + name + "!");
}

Tipp: In Java delegiert man oft von der einfacheren zur komplexeren Methode, um Code-Duplikation zu vermeiden.

Best Practices

1. Delegieren statt duplizieren

// SCHLECHT: Code-Duplikation
static String formatiere(String text) {
    return "*** " + text + " ***";
}
static String formatiere(String text, boolean grossbuchstaben) {
    var t = grossbuchstaben ? text.toUpperCase() : text;
    return "*** " + t + " ***"; // Gleiche Logik!
}

// GUT: Delegieren
static String formatiere(String text) {
    return formatiere(text, false);
}
static String formatiere(String text, boolean grossbuchstaben) {
    var t = grossbuchstaben ? text.toUpperCase() : text;
    return "*** " + t + " ***";
}

2. Konsistentes Verhalten

Alle ueberladenen Varianten sollten sich gleich verhalten, nur mit unterschiedlichen Eingaben:

// GUT: Alle addieren
static int addiere(int a, int b) { return a + b; }
static double addiere(double a, double b) { return a + b; }
static int addiere(int a, int b, int c) { return a + b + c; }

// SCHLECHT: Unterschiedliches Verhalten!
static int berechne(int x) { return x * 2; }      // Verdoppelt
static int berechne(int x, int y) { return x - y; } // Subtrahiert?!

Uebungen

Uebung 1: Maximum-Methode

Schreibe ueberladene Methoden maximum(), die das Maximum von 2, 3 oder einem Array von int-Werten finden.

Uebung 2: Begruessung

Schreibe ueberladene Methoden begruesse():

  • begruesse() — gibt “Hallo Welt!” aus
  • begruesse(String name) — gibt “Hallo [name]!” aus
  • begruesse(String name, int alter) — gibt “Hallo [name], du bist [alter]!” aus

Uebung 3: Konverter

Schreibe ueberladene Methoden zuString(), die int, double, boolean und int-Array in Strings umwandeln.

Uebung 4: Array-Ersteller

Schreibe ueberladene Methoden erstelleArray():

  • erstelleArray(int groesse) — erstellt ein Array mit Nullen
  • erstelleArray(int groesse, int wert) — erstellt ein Array gefuellt mit wert
  • erstelleArray(int von, int bis, int schritt) — erstellt ein Array mit Zahlenreihe

Was kommt als Naechstes?

Jetzt kennst du die Grundlagen von Methoden vollstaendig! In der naechsten Lektion starten wir mit Klassen und Objekte — dem Herztueck der objektorientierten Programmierung in Java.

Zusammenfassung

  • Ueberladung = gleicher Methodenname, unterschiedliche Parameter
  • Java waehlt die passende Methode anhand der Signatur (Name + Parametertypen)
  • Der Rueckgabetyp allein reicht nicht fuer Ueberladung
  • Java bevorzugt: exakt > Widening > Autoboxing > Varargs
  • Delegieren statt Code duplizieren: Einfache Variante ruft komplexe auf
  • Alle ueberladenen Methoden sollten sich konsistent verhalten

Pro-Tipp: Ueberladung ist besonders bei Konstruktoren nuetzlich — du kannst verschiedene Wege anbieten, ein Objekt zu erstellen. In IntelliJ zeigt dir Ctrl + P (Parameter Info) alle verfuegbaren ueberladenen Varianten einer Methode an. So siehst du sofort, welche Optionen du hast, ohne in die Dokumentation schauen zu muessen!

Zurück zum Java Kurs