Überschreibt generischen Rückgabetyp von der Schnittstelle

8

Ich habe mehrere Schnittstellen:

%Vor%

Warum arbeitet der Compiler bei einer Klasse, die Fetcher implementiert, mit dieser Methodendeklaration:

%Vor%

dies sind beide falsche Deklarationen:

%Vor%

wo EndpointImpl implements Endpoint<FetchableImpl> .

Meine Intuition wäre, dass der Parameter etwas haben würde, das angibt, dass es sich um einen Endpunkt handelt, der sich mit dem spezifischen Typ von Fetchable befasst. Warum benötigt der Compiler nur ein direktes Endpoint , auch wenn die Schnittstellenmethode Endpoint<T> benötigt?

    
Indigenuity 07.08.2015, 04:22
quelle

2 Antworten

0

Ihre Deklaration der Interface-Methode erfordert eine Methode, die mit jedem Typ von EndPoint umgehen kann:

%Vor%

Aber in Ihren Methodenimplementierungen beschränken Sie es auf einen spezifischeren Typ von EndPoint .

%Vor%

Daher sind dies keine gültigen Implementierungen der Schnittstellenmethode. Sie decken nicht alle Fälle ab, die die Schnittstelle erfordert.

Vielleicht möchten Sie ein generisches Fetcher deklarieren und dann das implementieren:

%Vor%

Wenn Sie möchten, dass die T in Endpoint<T> gleich der T ist, die von der Methode zurückgegeben wird, können Sie die Deklaration der Interface-Methode beibehalten und dieselbe Deklaration in Ihrer verwenden Implementierungsklasse:

%Vor%     
Robby Cornelissen 07.08.2015, 04:33
quelle
0

Kurz gesagt, das erste funktioniert wegen der rohen Typen, während die nächsten zwei aufgrund von Konflikten in der Methodensignatur nach dem Löschen fehlschlagen.

Denken Sie daran, dass Ihre Methode Fetcher::fetch <T extends Fetchable> T fetch(Endpoint<T>) ist und Implementierer von Fetcher diese Methode implementieren müssen. Eine gute Denkweise ist das Liskov-Substitutionsprinzip , das im Grunde sagt: "Wenn Ihr statischer Typ von SuperClass ist, dann Es sollte nicht darauf ankommen, welche SubClass Sie haben, sie sollten alle nur funktionieren, wie die SuperClass sagt. "

Lassen Sie uns sehen, wie Ihre zweiten beiden Deklarationen damit umgehen, indem Sie sich vorstellen, dass jemand ein Fetcher hat und es als solches aufruft:

%Vor%

Wie Sie sehen können, kann die fetch -Methode nicht EndpointImpl oder Endpoint<FetchableImpl> verwenden, um zu funktionieren. Es muss wirklich ein Endpoint<T> sein.

Sie könnten auch das generische Element in Ihrer Methodensignatur ignorieren und das Override vom unformatierten Typ haben (dh vom Typ gelöschter Typ). Das hast du mit dem ersten deiner Overrides gemacht ( FetchableImpl fetch(Endpoint) ), aber rohe Typen verlieren die Typensicherheit und haben ein paar andere Probleme, daher würde ich es nicht empfehlen.

Wenn Abwickler für jede Art von Endpunkt spezialisiert werden sollen, sollten Sie die generische Deklaration verwenden und sie auf die Schnittstelle Fetcher setzen:

%Vor%

Jetzt können Sie ein FetcherImpl implements Fetcher<EndpointImpl> haben.

    
yshavit 07.08.2015 04:37
quelle

Tags und Links