2012-09-27 8 views
5

Ho una classe generica astratta:Java Generics: Richiede generico per essere sottoclasse di un certo tipo

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; 
    } 
} 

Ho bisogno della sottoclasse generica di essere una sottoclasse di questa classe. In altre parole, il generico deve essere una sottoclasse di AbstractMessageHandler. Questo comunque mi dà problemi di compilazione. Qualcuno può farmi sapere cosa sto facendo di sbagliato?

Grazie

+0

Inviare l'errore del compilatore. E, si spera, si voglia solo richiedere una sottoclasse generica, 'T', che sia quella dell'interfaccia' che 'AbstractMessageHandler' implementi teoricamente, che immagino sia chiamata' MessageHandler'. In relazione a ciò, il parametro "setResponseValues" dovrebbe molto probabilmente prendere come parametro "Message" e non "AbstractMessage". Questi sono requisiti che limitano inutilmente, a meno che non ci sia semplicemente 'interfaccia' che implementano. – pickypg

+0

Senza contesto, immagino che AbstractMessageHandler nel vincolo del tipo stesso richieda un argomento di tipo. Sei sicuro che questo sia il miglior design per il tuo problema? Oppure intendevi "AbstractMessageHandler ?" –

risposta

7

è necessario seguire l'esempio della classe Enum:

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

Non sono d'accordo. Non vedo alcun beneficio di questo tipo su '>' dato il codice che ha dato. In ogni caso, 'Enum' è un caso speciale perché le sottoclassi di' Enum' sono create dal linguaggio e sono costrette a sottoclasse 'Enum' con il parametro generico esatto di se stessi. Questo non è vero per qualsiasi altra situazione. Non puoi forzarlo in nessuna altra situazione. – newacct

+0

@newacct: in realtà, è possibile. Hai provato? questo è in realtà un modello molto utile. l'ho usato nel mio codice quindi so che funziona. – jtahlborn

+0

Se si dispone di 'classe Foo estende AbstractMessageHandler {...}' allora si può avere 'classe Bar estende AbstractMessageHandler {...}'. Quindi cosa porta veramente questo limite? – newacct

0

Nella tua definizione generica che si possono fare <T extends SomeClass>

Per esempio:

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

Nel tuo caso, sembra che T dovrebbe estendere alcune Response di classe, e non AbstractMessageHandler.

+1

Nota: è nella prima riga. Sta colpendo un altro problema. – pickypg

+0

Sì, ha aggiunto che mentre lo stavo scrivendo. –

0

Dal codice dato, non sembra che ci sia alcuna necessità di rendere la classe generica. Che ne dite di un metodo generico invece (ho anche fatto lo statico, in quanto non sembra che è necessario utilizzare l'oggetto corrente a tutti):

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; 
    } 
} 

O, meglio ancora, basta definire un metodo su AbstractMessageHandler che opera sull'oggetto corrente. Quindi non hai bisogno di questo metodo statico e non hai questo strano parametro che restituisci sempre.

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