Methoden-Überladung
Lerne Methoden-Überladung (Overloading) in Java: Mehrere Methoden mit gleichem Namen, aber verschiedenen Parametern. Mit praktischen Beispielen.
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 unterscheiden | Beispiel |
|---|---|
| Anzahl der Parameter | add(int a) vs. add(int a, int b) |
| Typen der Parameter | add(int a) vs. add(double a) |
| Reihenfolge der Typen | log(String s, int i) vs. log(int i, String s) |
NICHT relevant fuer Ueberladung:
| Zaehlt NICHT | Beispiel |
|---|---|
| Rueckgabetyp | int add(int a) vs. double add(int a) — FEHLER! |
| Parameternamen | add(int x) vs. add(int y) — FEHLER! |
| Zugriffsmodifizierer | public 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:
| Aspekt | Ueberladung (Overloading) | Ueberschreibung (Overriding) |
|---|---|---|
| Was | Gleicher Name, andere Parameter | Gleicher Name, gleiche Parameter |
| Wo | In derselben Klasse | In Unterklasse |
| Wann entschieden | Beim Kompilieren | Zur Laufzeit |
| Vererbung | Nicht noetig | Erfordert 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!” ausbegruesse(String name)— gibt “Hallo [name]!” ausbegruesse(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 NullenerstelleArray(int groesse, int wert)— erstellt ein Array gefuellt mitwerterstelleArray(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!