2012-09-27 6 views
5

ich eine abstrakte generische Klasse haben:Java Generics: Erfordern allgemeine Unterklasse eines bestimmten Typs sein

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler> 
{ 
    public abstract List<String> getTypesOfMessages(); 
    public abstract void handleMessage(String message, CometClient client); 

    public T setResponseValues(AbstractMessage request, T response) 
    { 
     response.setCompanyId(request.getCompanyId()); 
     response.setMessageGroup(request.getMessageGroup()); 
     response.setUserId(request.getUserId()); 
     response.setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 

     return response; 
    } 
} 

Ich brauche die allgemeine Unterklasse eine Unterklasse dieser Klasse zu sein. In anderen Worten, das generische muss eine Unterklasse von AbstractMessageHandler sein. Dies gibt mir jedoch Kompilierungsfragen. Kann mir jemand sagen, was ich falsch mache?

Dank

+0

Geben Sie den Compilerfehler ein. Und hoffentlich wollen Sie wirklich nur eine generische Unterklasse, 'T', als diejenige der' Schnittstelle', die 'AbstractMessageHandler' theoretisch implementiert, die ich mir vorstelle, heißt' MessageHandler'. In Verbindung damit sollte der 'setResponseValues' höchstwahrscheinlich als Parameter eine 'Message' und nicht' AbstractMessage' nehmen. Dies sind unnötig einschränkende Anforderungen, es sei denn, es gibt einfach keine "Schnittstelle", die sie implementieren. – pickypg

+0

Ohne Kontext würde ich mir vorstellen, dass der AbstractMessageHandler in Ihrer Typ-Einschränkung selbst ein Typargument benötigt. Sind Sie sicher, dass dies das beste Design für Ihr Problem ist? Oder meintest du 'AbstractMessageHandler ? ' –

Antwort

7

Sie müssen das Beispiel der Enum-Klasse folgen:

public abstract class AbstractMessageHandler<T extends AbstractMessageHandler<T>> 
+0

Ich stimme nicht zu. Ich sehe keine Art Vorteil davon über '>' angesichts der Code, den er gegeben hat. In jedem Fall ist 'Enum' ein Sonderfall, weil die Unterklassen von' Enum' von der Sprache erzeugt werden und gezwungen werden, 'Enum' mit dem exakten generischen Parameter von sich selbst zu untergliedern. Das trifft auf keine andere Situation zu. Das kannst du in keiner anderen Situation erzwingen. – newacct

+0

@newacct - eigentlich können Sie. Hast Du es versucht? das ist eigentlich ein sehr handliches Muster. Ich habe es in meinem Code verwendet, damit ich weiß, dass es funktioniert. – jtahlborn

+0

Wenn Sie haben 'Klasse Foo erweitert AbstractMessageHandler {...}' dann können Sie haben 'Klasse Bar erweitert AbstractMessageHandler {...}'. Also, was bewirkt dieses gebunden wirklich? – newacct

0

In Ihrer allgemeinen Definition Sie <T extends SomeClass>

Zum Beispiel kann:

abstract class Processor<T extends String> { 
    abstract T process(); 
} 

In Ihrem Fall sieht es aus wie T einig Response Klasse erweitern sollte, und nicht AbstractMessageHandler.

+1

Hinweis: Er ist in der ersten Zeile. Er trifft ein anderes Problem. – pickypg

+0

Ja, fügte er hinzu, während ich es schrieb. –

0

Aus dem Code gegeben, es scheint nicht, wie es erforderlich ist, die Klasse generic zu machen. Wie über eine generische Methode statt (ich habe es sogar statisch gemacht, wie es scheint nicht, dass Sie das aktuelle Objekt überhaupt verwenden müssen):

public abstract class AbstractMessageHandler 
{ 
    public static <T extends AbstractMessageHandler> T setResponseValues(AbstractMessage request, T response) 
    { 
     response.setCompanyId(request.getCompanyId()); 
     response.setMessageGroup(request.getMessageGroup()); 
     response.setUserId(request.getUserId()); 
     response.setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 

     return response; 
    } 
} 

Oder noch besser definiert nur eine Methode auf AbstractMessageHandler Das funktioniert für das aktuelle Objekt. Dann brauchen Sie diese statische Methode nicht, und Sie haben nicht diesen seltsamen Parameter, den Sie immer zurückgeben.

public abstract class AbstractMessageHandler 
{ 
    public void setResponseValues(AbstractMessage request) 
    { 
     setCompanyId(request.getCompanyId()); 
     setMessageGroup(request.getMessageGroup()); 
     setUserId(request.getUserId()); 
     setTimeStamp(AbstractMessage.getCurrentTimeStamp()); 
    } 
} 
Verwandte Themen