Die Überladung von Methodennamen in Java
Überladung
Mehrere verschiedene Methoden dürfen mit demselben Namen (unten »p«) definiert werden, wenn sich die Anzahl oder der Typ ihrer Parameter hinreichend unterscheidet.
Main.java
public final class Main
{public static void p()
{ java.lang.System.out.println(); }public static void p( final java.lang.String text )
{ java.lang.System.out.println( text ); }public static void main( final java.lang.String[] args )
{ p( "Alpha" ); p(); p( "Beta" ); }}java.lang.System.out
Alpha
Beta
In dem obigen Beispielprogramm wird zuerst die Methode mit der Signatur »p(java.lang.String)«, dann die Methode mit der Signatur »p()« und schließlich wieder die Methode mit der Signatur »p(java.lang.String)« aufgerufen.
Mehrere Methoden
Ein einfacher Methodenname kann auch für mehrere Methoden verwendet werden, wenn diese sich in ihrem Parametertyp unterscheiden.
Main.java
public final class Main
{ public static java.lang.String type( final int i ){ return "int"; }
public static java.lang.String type( final double x ){ return "double"; }
public static java.lang.String type( final java.lang.String s ){ return "java.lang.String"; }
public static void main( java.lang.String[] args )
{ java.lang.System.out.println( type( 1. ));
java.lang.System.out.println( type( 1 ));
java.lang.System.out.println( type( "a" )); }}java.lang.System.out
double
int
java.lang.String
Es ist allerdings nicht immer möglich, den Typ von Ausdrücken auf die hier gezeigte Weise zu erkennen. Dies geht aber beispielsweise, wenn es nur darum geht, die drei oben gezeigten Typen zu unterscheiden.
Main.java
public final class Main
{public static void printDouble( final double wert )
{ java.lang.System.out.print( " Kommazahl: " + wert ); }public static void printInt( final int wert )
{ java.lang.System.out.print( "ganze Zahl: " + wert ); }public static void main( final java.lang.String[] args )
{ printInt( 3 ); java.lang.System.out.println();
printDouble( 3.14 ); java.lang.System.out.println(); }}java.lang.System.out
ganze Zahl: 3
Kommazahl: 3.14
Wenn zwei oder mehr Definitionen für einen Bezeichner im selben Bereich gelten, dann sagt man auch, diese Bezeichner sei überladen. Ein überladener Methodenname gehört also zu mehreren, verschiedenen Methoden. Wenn ein überladener Methodenname auf Argumente angewendet wird, dann wird der Typ der Argumente mit dem Typ der Parameter der Methoden mit diesem Namen verglichen, um die anzuwendende Methode zu bestimmen.
Mehrere Methoden die innerhalb eines Gültigkeitsbereichs den gleichen Namen teilen müssen sich in ihrer Signatur unterscheiden, sie müssen sich also in der Zahl oder wenigstens dem Datentyp ihrer Parameter ausreichend unterscheiden.
In dem folgenden Beispiel werden zwei Methoden mit dem Bezeichner "print" definiert, deren Argument vom Typ "int" bzw. vom Typ "double" ist.
Main.java
public final class Main
{public static void print( final double wert )
{ java.lang.System.out.print( " Kommazahl: " + wert ); }public static void print( final int wert )
{ java.lang.System.out.print( "ganze Zahl: " + wert ); }public static void main( final java.lang.String[] args )
{ print( 3 ); java.lang.System.out.println();
print( 3.14 ); java.lang.System.out.println(); }}java.lang.System.out
ganze Zahl: 3
Kommazahl: 3.14
Ohne die Möglichkeit der Methodennamensüberladung, müßte man den beiden Methoden verschiedene Namen geben. Die Namen wären so aber mühevoller zu erlernen und ihre Verschiedenheit wäre unpassend, wenn sie das gleiche Konzept darstellen, nur für unterschiedliche Datentypen. Die Methodennamensüberladung erlaubt hier eine viel natürlichere Formulierung unter Beibehaltung der Typstrenge, durch die Kontrolle der Verwendung von Ausdrücken anhand ihres Datentyps bei der maschinellen Analyse eines Java -Programms.
Erweiterung von Methoden
Eine Anwendung der Überladung von Methodennamen ist die Möglichkeit zur kompatiblen Erweiterung von Methodenschnittstellen. Eine Methode mag zunächst beispielsweise zwei Parameter haben. Es kann sich dann aber später herausstellen, daß es hilfreich wäre, einen weiteren Parameter zu der Methode hinzuzufügen. Dann müßte alle Klienten der Methode aber entsprechend angepaßt werden, was nicht immer möglich ist.
Dank der Möglichkeit zur Überladung von Methodennamen kann dann aber eine weitere Methode mit gleichem Namen und einem zusätzlichen Parameter definiert werden, ohne daß die bisher schon existierende Methodendefinition mit zwei Parametern dazu verändert werden muß. Dann können die bisherigen Klienten weiterhin die bisherige Methode mit zwei Parametern verwenden, während neuere Klienten die neue Methode mit drei Parametern verwenden können.
Methode namens »main«
Auch die Methode »main« darf überladen werden. Beim Programmstart wird immer »main( java.lang.String[] args )« aufgerufen.
Main.java
public final class Main
{public static void main()
{ java.lang.System.out.println( "main() was called.\n" ); }public static void main( final java.lang.String[] args )
{ main(); }}transcript
main() was called.
Übungsfragen
? Ausgabe vorhersagen
Was ist die Ausgabe des folgenden Programms?
Main.java
public final class Main
{ public static int f( ){ return 0; }
public static java.lang.String f( final double x ){ return "alpha"; }
public static double f( final int x ){ return 1; }public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( f() );
java.lang.System.out.println( f( f() ));
java.lang.System.out.println( f( f( f() ))); }}
? Ausgabe vorhersagen (1)
Was ist die Ausgabe des folgenden Programms?
public final class Main
{public static void m( final int i )
{ java.lang.System.out.println( i ); }public static int m()
{ return 12; }public static void main( final java.lang.String[] args )
{ m( m() ); }}
? Ausgabe vorhersagen (2)
Was ist die Ausgabe des folgenden Programms?
public final class Main
{public static void m( final int i )
{ java.lang.System.out.println( "3" ); }public static int m()
{ java.lang.System.out.println( "4" );
return 12; }public static void main( final java.lang.String[] args )
{ m( m() ); }}
Übungsaufgaben
/ »println« definieren
Schreiben Sie eine Deklaration einer println-Methode mit einem String-Parameter und einer println-Methode mit einem double-Parameter in das folgende Programm, so daß das Programm dann »alpha« und »3« auf je einer Zeile ausgibt. (Die Methode »main« soll dabei nicht verändert werden.)
public final class Main
{/* Hier Methodendeklarationen einfügen */
public static void main( final java.lang.String[] args )
{ println( "alpha" );
println( 3 ); }}
/ »printtype« definieren
Definieren Sie zwei Wirkmethoden "printtype" jeweils für ein Argument vom Datentyp "int" und vom Datentyp "double". Jede Wirkmethode soll den Namen des Datentyps ihres Argumentes ausgeben.
Main.java
public final class Main
{ // ... Hier Wirkmethoden definierenpublic static void main( final java.lang.String[] args )
{ printtype( 0 ); java.lang.System.out.println();
printtype( 3.1415926 ); java.lang.System.out.println(); }}java.lang.System.out
int
double