2017-09-04 5 views
0

Ich habe eine Klasse, die die Antwort enthält, die an die Benutzeroberfläche gesendet werden soll. Der Entwurf ist als:Geschachtelte generische polymorphe Rückgabetypen in einer Klasse

class Response<T extends CustomObject> { 
    private String var1; 
    private String var2; 
    private List<T> custom; (eg. customOne, customTwo) 
} 

ich verschiedene Objekte wie benutzerdefinierte Objekte haben können, die CustomObject und auf der Grundlage dieser Response-Klasse erweitern unterschiedliche customObject Liste haben.
Nach dem Anwenden der Dienstlogik bekomme ich eine rohe Antwort und basierend auf dem benutzerdefinierten Objekt versuche ich, anders zu analysieren.
CusomOne und CustomTwo unterschiedliche Struktur haben wie:

class CustomOne extends CustomObject { 
    private String v1; 
} 
class CustomTwo extends CustomObject { 
    private String v2; 
} 

ich eine abstrakte Parsing-Funktion haben, die basierend auf dem Objekt aufgerufen wird, der gerichtet. Die Funktion ist wie folgt definiert:

public abstract ResponsePayLoad<? extends CustomObject> parseResponse(String response); 

ReponsePayLoad ist eine weitere Klasse mit anderen Feldern, einschließlich CustomObject. Der Bauplan für Klasse ResponsePayLoad ist als:

class ResponsePayLoad<T extends CustomObject> { 
    private String varX; 
    private List<T> value; 
} 

Parsing-Funktion für beide customObjects wird wie:

ResponsePayLoad<CustomObject> responseObj = parseResponse(response); 

I:

public ResponsePayLoad<customOne> parseResponse(String response){ 
    CustomOne one = ; // parsingLogic 
    return one; 
} 
public ResponsePayLoad<customTwo> parseResponse(String response){ 
    CustomTwo two = ; // parsingLogic 
    return two; 
} 

In meiner Dienstlogik, wenn ich den Code wie schreiben Ich muss es auf ResponsePayLoad tippen, das ich nicht möchte.
Kann mir jemand sagen, wie ich mit "?" in abstrakter Funktion und immer noch die gleiche Logik? Außerdem möchte ich nicht wie oben beschrieben tippen. Jede Hilfe wäre willkommen.

Antwort

0

Wenn ich Sie richtig verstanden habe, geben Sie den Typ parseResponse zum Beispiel ResponsePayLoad<CustomOne> bzw. ResponsePayLoad<CustomTwo> zurück.

Dann ist es nicht möglich, das Ergebnis zu speichern, in

ResponsePayLoad<CustomObject> responseObj = parseResponse(response);

Da das Ergebnis nicht niedergeschlagenen können. In einer generischen Art und Weise würden Sie

ResponsePayLoad<? extends CustomObject> responseObj = parseResponse(response);

verwenden aber wieder speichern Sie die CustomOne und CustomTwo Objekte als CustomObject dh Sie bestimmen den Typ-Informationen verlieren. Dann ist eine Besetzung notwendig.

0

Der Grund, warum Sie

ResponsePayLoad<CustomObject> responseObj = parseResponse(response); 

da die parseResponse Methode gibt ResponsePayload unbekannten Typs (ResponsePayLoad<? extends CustomObject>) werfen müssen.

Alles, was hier verstanden wird, ist, dass der unbekannte Typ ein Subtyp von CustomObject sein kann. Es könnte CustomObject selbst sein (wie in Ihrem Fall), oder einige seiner Unterklassen (CustomOne, CustomTwo etc.) aber es muss nicht buchstäblich CustomObject erweitern.

Daher Casting die vollständige Antwort in ResponsePayload weiter macht es generisch genug, obwohl Sie von den Compilern über die ungeprüfte Besetzung gewarnt werden müssen, während dies tun.

erklärt dies mit einem besseren Beispiel.


... wie kann ich mit überspringen "?" in abstrakte Funktion und immer noch die gleiche Logik?

Der andere Weg explizite Typumwandlung zu vermeiden, ist ResponsePayload von Ihrer parseResponse Methode zurückzukehren, indem sie als erklären:

public abstract ResponsePayLoad parseResponse(String response); 
Verwandte Themen