2012-09-27 14 views
5

tengo una clase genérica:Java Genéricos: Requerir genérico para ser subclase de un cierto 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; 
    } 
} 

necesito la subclase genérico para ser una subclase de esta clase. En otras palabras, el genérico debe ser una subclase de AbstractMessageHandler. Sin embargo, esto me da problemas de compilación. ¿Alguien me puede decir lo que estoy haciendo mal?

Gracias

+0

Publique el error del compilador. Y, afortunadamente, lo único que desea es requerir que una subclase genérica, 'T', sea la de la' interfaz' que 'AbstractMessageHandler' implementa teóricamente, que me imagino que se llama' MessageHandler'. Relacionado, el 'setResponseValues' debería tener como parámetro un' Mensaje' y no 'AbstractMessage'. Estos son requisitos que limitan innecesariamente, a menos que simplemente no haya 'interfaz' que implementen. – pickypg

+0

Sin contexto, me imagino que el AbstractMessageHandler en su restricción de tipo en sí mismo requiere un argumento de tipo. ¿Estás seguro de que este es el mejor diseño para tu problema? ¿O quisiste decir 'AbstractMessageHandler ?' –

Respuesta

7

que debe seguir el ejemplo de la clase de enumeración:

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

No estoy de acuerdo. No veo ningún tipo de beneficio de esto sobre '>' dado el código que ha dado. En cualquier caso, 'Enum' es un caso especial porque las subclases de 'Enum' son creadas por el lenguaje y se ven obligadas a subclasificar' Enum' con el parámetro genérico exacto de ellos mismos. Eso no es verdad en ninguna otra situación. No puedes forzar eso en ninguna otra situación. – newacct

+0

@newacct - en realidad, puedes. ¿Lo intentaste? este es en realidad un patrón muy útil. Lo he usado en mi código, así que sé que funciona. – jtahlborn

+0

Si tiene 'clase Foo extiende AbstractMessageHandler {...}' entonces puede tener 'clase Barra extiende AbstractMessageHandler {...}'. Entonces, ¿qué logra realmente este límite? – newacct

0

En su definición genérica que puede hacer <T extends SomeClass>

Por ejemplo:

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

En su caso, parece que T debe extender un poco de clase Response, y no AbstractMessageHandler.

+1

Nota: él está en la primera línea. Él está golpeando algún otro problema. – pickypg

+0

Sí, agregó que mientras lo escribía. –

0

Desde el código dado, que no parece que haya ninguna necesidad de hacer la clase genérica. ¿Qué tal un método genérico en vez (aunque lo he hecho estático, ya que no parece que se tiene que utilizar el objeto actual en absoluto):

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 mejor aún, simplemente definir un método de AbstractMessageHandler que opera en el objeto actual. Entonces no necesitas este método estático, y no tienes este parámetro raro que siempre regresas.

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