2012-09-15 5 views
12

Beim Überschreiben einer Methode einer Superklasse ermöglicht Java, dass der Rückgabetyp kovariant ist.Warum sind kontravariante Parametertypen in Java nicht zum Überschreiben zugelassen?

Warum sind kontravariante Parametertypen im Gegensatz nicht erlaubt, wenn Methoden überschrieben werden?

+4

mögliche Duplikate von [Warum gibt es keine Parameterkontra-Varianz für das Überschreiben?] (Http://stackoverflow.com/questions/2995926/why-is-there-no-parameter-contra-variance-for- overriding) –

+0

Danke. Ich habe das gesehen, hatte aber Schwierigkeiten, die Antwort in C++ zu verstehen, da ich mit C++ völlig nicht vertraut bin. Ich dachte, es wäre einfacher, spezifisch nach Java zu fragen. – Will

+0

Ich lese den verlinkten Post und soweit ich verstehe, Gewinn von dieser Funktion nicht überwiegen Überraschungsfaktor. Und es ist nicht so schwer, eine überladene Methode für eine bestimmte Implementierung bereitzustellen. Ich meine, welche anderen Anwendungsfälle für diese Funktion sehen Sie? außer die Methode direkt auf der Klasse aufzurufen? –

Antwort

15

Weil das heißt overloading.

Insbesondere der Rückgabetyp kann kovariant sein, da er beim Überladen nicht berücksichtigt wird und daher immer noch der Implementierung der Oberklasse oder Schnittstelle entspricht. Parameter werden beim Überladen berücksichtigt. Sie können sehr gut eine Optimierung mit Number doSomethingWithNumber(Integer value) im Vergleich zu Number doSomethingWithNumber(Number value) haben.

+0

Unter der Annahme, dass kontravariante Parameter immer noch Vorrang haben, welche Probleme würden wir auftreten? Ich bin auf der Suche nach etwas wie: http://StackOverflow.com/A/2996901/715236, aber was wäre schlecht über die Methode in einer Unterklasse überschreiben mehrere in einer Oberklasse? – Will

+0

Das größte Problem wäre die Unfähigkeit, Überladungen bereitzustellen, wenn irgendwo in der Kette eine Überlastung des Basistyps auftritt. Dies würde Chaos bei polymorphen Funktionsaufrufen zur Folge haben, da sich die Suche von einer einfachen gleichartigen Signatur zu einer gleichwertigen oder grundlegenderen Signatur ändern müsste, und was sollten Sie anrufen, wenn Sie beide haben, aber die spezifischere aufrufen? Aus der Entwurfsperspektive gilt: Wenn "A erweitert B" und "B erweitert C", aber "B" die "Leere f (Objekt o)" - Implementierung von Ihrem Link darstellt, dann hat "A" keine Möglichkeit, das Mehr zu implementieren spezifische überladene Methoden. Das wäre ein Albtraum. – pickypg

+1

Am wichtigsten, denke ich, würde es zu APIs führen, die faul überschrieben werden, was zu einer Menge unglaublich hässlichem Code führen würde, der intern verwendet würde, um die entsprechende Methode aufzurufen: 'void f (Object o) {if (o instanceof Integer) f ((Integer) o); } '. Und dann muss man fragen, wie würde das überhaupt funktionieren? Um das überschreibende Verhalten zu erlauben, würde es bedeuten, dass die Parametermethode "Object" die Parametermethode "Integer" außer Kraft setzt und der obige Code daher eine unendliche rekursive Schleife (bis der Stack übergelaufen ist) verursacht, da er direkt auf die '' zurückfällt Objektmethode. – pickypg

Verwandte Themen