1. Methodenüberladung
Methodenüberladung (method overloading) – das ist die Möglichkeit, in einer Klasse mehrere Methoden mit demselben Namen, aber unterschiedlichen Parameterlisten (Typen, Anzahl oder Reihenfolge der Argumente) zu deklarieren. Wenn Sie eine solche Methode aufrufen, entscheidet der Compiler selbst, welche Version verwendet wird, abhängig von den übergebenen Argumenten.
Alltagsanalogie
Stellen Sie sich vor, Sie rufen den Bank‑Support an. Sie können verschiedene Nummern wählen – für Privatkunden, für Firmenkunden, für VIP‑Kunden. Die Nummern sind unterschiedlich, das Ziel ist dasselbe – Hilfe zu bekommen. In der Programmierung ist die Methodenüberladung wie eine einzige Supportnummer, die Sie je nach Anliegen (oder den Parametern, die Sie übergeben) automatisch mit dem richtigen Operator verbindet.
Syntax der Überladung in Java
In Java ist die Methodenüberladung sehr einfach: Sie deklarieren mehrere Methoden mit demselben Namen, aber unterschiedlichen Parametern.
Wichtige Regel:
Überladung unterscheidet sich nur anhand der Parameterliste (Typ, Anzahl, Reihenfolge).
Eine Überladung nur nach dem Rückgabetyp ist nicht zulässig!
Der Compiler kann Methoden nicht unterscheiden, wenn sie denselben Namen und dieselben Parameter haben, selbst wenn sich der Rückgabetyp unterscheidet.
Einfaches Beispiel
public class Printer {
// Ausgabe einer Ganzzahl
void print(int x) {
System.out.println("int: " + x);
}
// Ausgabe einer Zeichenkette
void print(String s) {
System.out.println("String: " + s);
}
// Ausgabe zweier Zahlen
void print(int x, int y) {
System.out.println("int, int: " + x + ", " + y);
}
}
Verwendung:
Printer printer = new Printer();
printer.print(42); // ruft print(int x) auf
printer.print("Hello!"); // ruft print(String s) auf
printer.print(5, 10); // ruft print(int x, int y) auf
Der Compiler bestimmt anhand der übergebenen Argumente selbst, welche Methode aufgerufen wird.
2. Wie der Compiler die passende Methode auswählt
Wenn Sie eine überladene Methode aufrufen, analysiert der Compiler die Argumentliste und sucht die am besten passende Version.
Auswahlkriterien:
- Übereinstimmung in der Anzahl der Argumente.
- Übereinstimmung der Typen jedes Arguments (oder die Möglichkeit einer Umwandlung, z. B. int → double).
- Wenn mehrere Methoden passen, wird die spezifischste gewählt.
Beispiel:
public class OverloadDemo {
void show(int x) {
System.out.println("show(int): " + x);
}
void show(double x) {
System.out.println("show(double): " + x);
}
public static void main(String[] args) {
OverloadDemo demo = new OverloadDemo();
demo.show(5); // show(int): 5
demo.show(5.5); // show(double): 5.5
}
}
Wenn Sie demo.show(5) aufrufen, wählt der Compiler show(int). Wenn Sie mit 5.5 aufrufen – wählt er show(double).
Typumwandlungen
Gibt es keine passende Methode, versucht der Compiler, die Argumenttypen umzuwandeln (z. B. int → double), jedoch nur, wenn das möglich und nicht mehrdeutig ist.
void print(double x) { /* ... */ }
print(5); // int 5 wird zu double 5.0 konvertiert
Überladung nur nach Rückgabetyp – funktioniert nicht!
Viele Einsteiger versuchen Folgendes:
// Fehler! Eine solche Überladung ist nicht möglich
int sum(int x, int y) { return x + y; }
double sum(int x, int y) { return (double) (x + y); }
Der Compiler weiß nicht, welche Methode Sie aufrufen wollen, wenn Sie einfach sum(2, 3) schreiben.
Merken Sie sich: Methodenüberladung ist nur über die Parameter möglich, nicht über den Rückgabetyp!
3. Überladung von Konstruktoren
Man kann nicht nur gewöhnliche Methoden, sondern auch Konstruktoren überladen!
public class Person {
String name;
int age;
// Konstruktor nur mit Name
public Person(String name) {
this.name = name;
this.age = 0; // Standardwert
}
// Konstruktor mit Name und Alter
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Verwendung:
Person p1 = new Person("Anna");
Person p2 = new Person("Boris", 25);
4. Praktische Beispiele
Calculator mit Überladung
Schreiben wir eine Klasse Calculator, die Zahlen unterschiedlichen Typs und in unterschiedlicher Anzahl addieren kann.
public class Calculator {
// Addition zweier Ganzzahlen
int add(int a, int b) {
return a + b;
}
// Addition dreier Ganzzahlen
int add(int a, int b, int c) {
return a + b + c;
}
// Addition zweier double
double add(double a, double b) {
return a + b;
}
}
Verwendung:
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3)); // 5
System.out.println(calc.add(1, 2, 3)); // 6
System.out.println(calc.add(2.5, 3.1)); // 5.6
Methodenüberladung in der Standardbibliothek
Sie sind der Überladung bereits begegnet, auch wenn Sie es vielleicht nicht bemerkt haben. Zum Beispiel ist die Methode println in System.out für verschiedene Typen überladen:
System.out.println("Hello"); // println(String)
System.out.println(123); // println(int)
System.out.println(3.14); // println(double)
System.out.println(true); // println(boolean)
Öffnen Sie den Quellcode der Klasse PrintStream – Sie werden Dutzende überladener Versionen von println sehen.
5. Wann sollte man Überladung verwenden
Methodenüberladung ist ein mächtiges Werkzeug, sollte aber mit Bedacht eingesetzt werden. Sie ist sinnvoll, wenn:
- die Logik der Methode gleich ist, die Parameter sich jedoch unterscheiden können.
- Sie die API der Klasse benutzerfreundlicher und flexibler machen möchten.
- sowohl alte als auch neue Aufrufvarianten unterstützt werden sollen.
Praxisbeispiel:
In unserer Lernanwendung (z. B. in einem Aufgabenmanager) kann man eine Methode zum Hinzufügen einer Aufgabe mit unterschiedlichen Parametern implementieren:
public class TaskManager {
void addTask(String description) { ... }
void addTask(String description, int priority) { ... }
void addTask(String description, int priority, String deadline) { ... }
}
Dieser Ansatz ist nicht nur bequem für die Nutzer des Codes, sondern macht Ihre Klasse auch flexibel für zukünftige Änderungen.
6. Überladung und varargs (variable Argumentanzahl)
In Java können Sie eine Methode mit variabler Argumentanzahl mithilfe von ... (varargs) deklarieren:
void printAll(String... messages) {
for (String msg : messages) {
System.out.println(msg);
}
}
Nun können Sie Folgendes aufrufen:
printAll("Hello");
printAll("One", "Two", "Three");
Auch mit varargs kann man überladen, aber Vorsicht: Wenn es zwei Methoden gibt und eine davon varargs verwendet, die andere jedoch eine feste Parameteranzahl hat, versucht der Compiler zuerst, eine exakte Übereinstimmung zu finden.
7. Typische Fehler bei der Methodenüberladung
Fehler Nr. 1: Verwechslung der Argumenttypen.
Wenn Sie die Methoden void process(int x) und void process(double x) haben, ruft process(5) die erste Version auf, und process(5.0) – die zweite. Wenn Sie jedoch process(5L) aufrufen, sucht der Compiler die beste Übereinstimmung und könnte eine nicht offensichtliche Überladung wählen (oder sogar Mehrdeutigkeit melden).
Fehler Nr. 2: Überladung mit Autoboxing/automatischer Umwandlung.
Wenn Sie void foo(Integer x) und void foo(Long x) haben, führt der Aufruf foo(5) zu einem Kompilierungsfehler – der Compiler weiß nicht, welche Methode er wählen soll, weil 5 sowohl zu Integer als auch zu Long konvertiert werden kann.
Fehler Nr. 3: Überladung nur nach Rückgabetyp.
Wie oben erwähnt, können Methoden, die sich nur im Rückgabetyp unterscheiden, nicht überladen werden.
Fehler Nr. 4: Überladung und Vererbung.
Wenn in der Basisklasse eine Methode deklariert ist und Sie in der Unterklasse eine Methode mit demselben Namen, aber anderer Signatur deklarieren, ist das eine Überladung, kein Überschreiben. Das wird oft verwechselt! Mehr dazu – in der nächsten Vorlesung.
GO TO FULL VERSION