Java: Überschreibt eine abstrakte Methode in der Unterklasse

7

Ich sollte das wirklich wissen, aber aus irgendeinem Grund verstehe ich Folgendes nicht.

Meine abstrakte Klasse enthält die folgende abstrakte Methode:

%Vor%

Ich habe auch eine andere Klasse wie folgt:

%Vor%

Dann habe ich in einer Unterklasse meiner abstrakten Klasse die folgende Implementierung, die nicht erlaubt ist, weil "eine Supertype-Methode überschrieben oder implementiert werden muss":

%Vor%

Folgendes ist jedoch erlaubt:

%Vor%

Ich verstehe, dass dies wahrscheinlich eine grundlegende Frage ist, aber ich bin etwas verwirrt. Wie kann ich eine Unterklasse von RuleDTO in der überschriebenen Methode zurückgeben, aber ich kann keine Unterklasse übergeben?

Danke

    
DJ180 19.07.2012, 21:45
quelle

6 Antworten

11

Sie brechen das Liskov-Prinzip: Alles, was eine Oberklasse tun kann, muss eine Unterklasse tun können. Die Oberklasse deklariert eine Methode, die jede Art von RuleDTO akzeptiert. In Ihrer Unterklasse akzeptieren Sie nur Instanzen von EvaluationRuleDTO. Was würde passieren, wenn Sie Folgendes tun würden?

%Vor%

Ein EvaluationRuleDTO ist ein RuleDTO, also muss es den durch RuleDTO definierten Vertrag erfüllen.

Die Methode in der Unterklasse kann eine Instanz von EvaluationRuleDTO anstelle von RuleDTO zurückgeben, da der Vertrag ein RuleDTO und EvaluationRuleDTO ein RuleDTO ist.

    
JB Nizet 19.07.2012, 21:52
quelle
4

Java ermöglicht die Kovarianz des Rückgabetyps für Überschreibungen, sodass Sie den Rückgabetyp einer Überschreibung als einen mehr abgeleiteten Typ angeben können. Java erlaubt jedoch keine Parametertyp-Kovarianz für Überschreibungen.

Der Grund für die Sicherheit ist, dass das Objekt, das Sie zurückgeben, mindestens die Funktionalität des weniger abgeleiteten Typs hat, sodass ein Client, der sich auf diese Tatsache verlässt, das zurückgegebene Objekt weiterhin korrekt verwenden kann.

Das ist jedoch bei den Argumenten nicht der Fall. Wenn es legal wäre, könnte ein Benutzer die abstrakte Methode aufrufen und einen weniger abgeleiteten Typ übergeben (da dies der in der abstrakten Klasse deklarierte Typ ist), aber dann könnte Ihre abgeleitete Überschreibung versuchen, auf das Argument als mehr abgeleiteten Typ zuzugreifen ( was es nicht ist), was zu einem Fehler führt.

Theoretisch hätte Java die Parametertyp contra -Varianz zulassen können, da dies typsicher ist: Wenn die Methode overriden nur ein less abgeleitetes Argument erwartet, Sie können nicht versehentlich eine Methode oder ein Feld verwenden, das nicht vorhanden ist. Leider ist das momentan nicht verfügbar.

    
dlev 19.07.2012 21:49
quelle
4

Wenn Sie eine Methode überschreiben, MÜSSEN Sie als Parametertyp den gleichen Typ oder einen allgemeineren (breiteren) Typ verwenden, niemals einen schmaleren Typ.

Denk einfach darüber nach. Wenn Sie eine Methode mit einem engeren Typ überschreiben könnten, würden Sie die Polymorphismus-Funktion aufheben, nicht einverstanden? Wenn Sie das tun, würden Sie das Liskow-Substitutionsprinzip brechen, wie JB Nizet in seiner Antwort sagte.

    
davidbuzatto 19.07.2012 21:48
quelle
0

Java 1.5 hat co-variant return Typen, weshalb es gültig ist

  

Der Rückgabetyp R2 der Unterklassenmethode kann sich von der Oberklasse unterscheiden   Rückgabetyp der Methode R1, aber R2 sollte ein Subtyp von R1 sein. d.h.   Die Rückgabetyp-Unterklasse kann ein Subtyp des Rückgabetyps der Oberklasse sein.

    
kosa 19.07.2012 21:48
quelle
0

Im frühen Java war das nicht der Fall, aber es wurde in Java 5.0 geändert.

  

Sie können nicht zwei Methoden in derselben Klasse mit Signaturen haben, die sich nur durch den Rückgabetyp unterscheiden. Bis zur Version J2SE 5.0 war es auch richtig, dass eine Klasse den Rückgabetyp der Methoden, die sie von einer Oberklasse erbt, nicht überschreiben konnte. In diesem Tipp erfahren Sie etwas über ein neues Feature in J2SE 5.0, das kovariante Rückgabetypen ermöglicht. Dies bedeutet, dass eine Methode in einer Unterklasse ein Objekt zurückgeben kann, dessen Typ eine Unterklasse des Typs ist, der von der Methode mit der gleichen Signatur in der Oberklasse zurückgegeben wird. Diese Funktion beseitigt die Notwendigkeit einer übermäßigen Typprüfung und Umwandlung.

Quelle: Ссылка

Dies bedeutet, dass die Rückgabetypen der überschreibenden Methoden Untertypen des Rückgabetyps der überschriebenen Methode sind.

    
Lion 19.07.2012 21:53
quelle
0

Siehe den folgenden Code:

%Vor%

Ja, ok, B IS AN A, aber was passiert, wenn jemand es tut:

%Vor%

A hat keine Balkenmethode. Deshalb darf das Argument kein Subtyp des Argumenttyps in der Methode sein, die überschrieben wird.

Die Rückgabe von A oder B in der Overriding-Methode ist in Ordnung. Das folgende Snippet wird kompiliert und läuft gut ..

%Vor%     
Koray Tugay 23.12.2016 18:28
quelle

Tags und Links