Überladung mit unterschiedlichem Rückgabetyp in Java?


104

Warum ist es nicht möglich, eine Funktion nur durch Ändern des Rückgabetyps zu überladen? Wird sich das in einer zukünftigen Version von Java ändern?

Ist dies übrigens nur als Referenz in C ++ möglich?


1

KNU, ​​die andere Antwort unterscheidet sich darin, dass sie die Frage allgemein und nicht sprachspezifisch stellt. Interessant ist auch, dass die akzeptierte Antwort anderer Fragen noch weiter geht, indem angegeben wird, dass die Java-JVM dies mit der Manipulation von Interna ermöglicht.
J Woodchuck

Antworten:


157

Sie können es nicht in Java tun, und Sie können es nicht in C ++ tun. Das Grundprinzip ist, dass der Rückgabewert allein nicht ausreicht, damit der Compiler herausfindet, welche Funktion aufgerufen werden soll:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

3
Ich dachte immer, wenn wir so etwas wie int i = foo () oder float f = foo () machen würden, würde es wissen, welches, aber wenn die Anweisung nur die Funktion ist, die der Compiler nicht wissen würde. Ich verstehe es. Vielen Dank.
Nunos

7
@nunos, selbst wenn es float f = foo () wäre, könnte der Compiler es nicht herausfinden, da sowohl ein int als auch eine gültige Eingabe für ein float wäre. Vergleiche float f = 7; (
Ist

5
@NomeN Aber Ihre Aussage legt nahe, dass func (int i) und func (float i) für den Compiler nicht zu unterscheiden sind - und wir alle wissen, dass dies nicht wahr ist. Der wahre Grund wird von Oded angegeben (siehe nächste Antwort) - es geht um die Signatur der Methode. Und übrigens. 7 ist definitiv eine ganze Zahl, während 7.0 oder 7f float ist ;-)
Ta Sas

7
7.0 ist nicht float, es ist double.
Fredoverflow

3
Die Tatsache, dass foo();ohne einen Rückgabetyp mehrdeutig wäre, ist nicht unbedingt ein Grund, ihn als Überladung zu verbieten. Es gibt Argumente, die Mehrdeutigkeiten verursachen können (z. B. foo(null);), die jedoch die Überladung nicht von Natur aus ungültig machen.
Shmosel

48

Der Grund dafür ist, dass Überladungen in Java nur für Methoden mit unterschiedlichen Signaturen zulässig sind .

Der Rückgabetyp ist nicht Teil der Methodensignatur und kann daher nicht zur Unterscheidung von Überladungen verwendet werden.

Siehe Definieren von Methoden in den Java-Tutorials.


4
Aber warum ist der Rückgabetyp nicht Teil der Signatur
andho

51
oh "nur weil"! Aha.
Andho

3
Der Rückgabetyp ist Teil der Methodensignatur. Schauen Sie sich einfach die Demontage der Klasse an.
Konmik

2
Es ist wirklich nicht @konmik - nicht nach den Regeln der Methodenüberladung. Versuch es. Gleicher Methodenname, gleiche Parametertypen in derselben Reihenfolge, unterschiedliche Rückgabetypen. Wird nicht kompiliert.
Oded

3
Ja, da der Rückgabetyp nicht Teil der Signatur ist . Die Signatur ist - der Name der Methode + die Typen und die Reihenfolge ihrer Parameter. Lesen Sie den Link, den ich in meiner Antwort angegeben habe: "Die Signatur der oben deklarierten Methode lautet: calculateAnswer(double, int, double, double)". Stellen Sie sicher, dass der Rückgabetyp @konmik nicht enthalten ist.
Oded

22

Vor Java 5.0 müssen beim Überschreiben einer Methode sowohl die Parameter als auch der Rückgabetyp genau übereinstimmen. In Java 5.0 wird eine neue Funktion namens kovarianter Rückgabetyp eingeführt. Sie können eine Methode mit derselben Signatur überschreiben, aber eine Unterklasse des zurückgegebenen Objekts zurückgeben. Mit anderen Worten, eine Methode in einer Unterklasse kann ein Objekt zurückgeben, dessen Typ eine Unterklasse des Typs ist, der von der Methode mit derselben Signatur in der Oberklasse zurückgegeben wird.


3
Ich war verblüfft, als ich das zum ersten Mal sah. Vielen Dank für die Erklärung, warum dies möglich ist!
Dylan Knowles

2
Überladen und Überschreiben sind unterschiedlich. Überladung beinhaltet nicht (notwendigerweise) Vererbung
Senseiwu

3
Diese Antwort mag für einen Neuling in Java irreführend klingen, da sie bei Überladung überhaupt nicht relevant ist , sondern überschreibt - eine ganz andere Sache.
Azizbekian

4

Overloaded Methoden in Java können unterschiedliche Rückgabetypen haben, da das Argument ebenfalls unterschiedlich ist.

Überprüfen Sie den Beispielcode.

public class B {

    public String greet() {
        return "Hello";
    }

    //This will work
    public StringBuilder greet(String name) {
        return new StringBuilder("Hello " + name);
    }

    //This will not work
    //Error: Duplicate method greet() in type B
    public StringBuilder greet() {
        return new StringBuilder("Hello Tarzan");
    }

}

Grundsätzlich wird der Rückgabetyp nicht berücksichtigt, nur die Argumente, traurig aber wahr
Alexander Mills

1

Der Compiler berücksichtigt bei der Unterscheidung von Methoden nicht den Rückgabetyp. Daher können Sie nicht zwei Methoden mit derselben Signatur deklarieren, selbst wenn sie einen anderen Rückgabetyp haben.


1

Der Rückgabetyp spielt beim Überladen einer Methode keine Rolle. Wir müssen nur sicherstellen, dass es keine Unklarheiten gibt!

Die einzige Möglichkeit für Java, die aufzurufende Methode zu ermitteln, besteht darin, die Typen der Argumentliste zu unterscheiden. Wenn der Compiler zwei Methoden mit demselben Namen und denselben Argumenttypen zulässt, kann nicht festgelegt werden, welche Methode aufgerufen werden soll.


0

Der Compiler berücksichtigt bei der Unterscheidung von Methoden nicht den Rückgabetyp. Daher können Sie nicht zwei Methoden mit derselben Signatur deklarieren, selbst wenn sie einen anderen Rückgabetyp haben.

Wenn Sie sich der Funktionsausführung bewusst sind, werden Sie wissen, dass beim Aufrufen einer Funktion der Definitionsteil ausgeführt wird und wir schließlich die return-Anweisung benötigen. Daher können wir sagen, dass return nach der gesamten Definition der Funktion erfolgt. Deshalb, wenn es zwei oder gibt mehr Funktionen mit gleichem Namen und gleichem Typ und Nr. von Argumenten dann zum Zeitpunkt des Aufrufs, wie der Compiler weiß, welches aufgerufen werden soll, da Funktionsname und Parameter identisch sind. Zum Zeitpunkt des ersten Aufrufs liegt der Fokus auf Argumenten und Funktionsnamen, und nach Abschluss der Funktionsdefinition beschäftigen wir uns schließlich mit der return-Anweisung.

Der Kompilierungszeitfehler ist besser als der Laufzeitfehler. Der Java-Compiler gibt also einen Compiler-Zeitfehler aus, wenn Sie dieselbe Methode mit denselben Parametern deklarieren.


Wie unterscheidet sich das von der akzeptierten Antwort? (Der Grund für den Fehler bei der Kompilierung ist auch, dass der Compiler nicht herausfinden kann, welche Methode aufgerufen werden soll. Wie soll also der richtige ausführbare Code generiert werden
?

-2

nein nicht wirklich möglich auf diese Weise können Sie nur durch keine Argumente oder Datentyp der Argumente überladen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.