Mi pregunta no es fácil de explicar con palabras, afortunadamente no es muy difícil de demostrar. Por lo tanto, tengan paciencia conmigo:¿Cómo mezclar adecuadamente los genéricos y la herencia para obtener el resultado deseado?
public interface Command<R>
{
public R execute();//parameter R is the type of object that will be returned as the result of the execution of this command
}
public abstract class BasicCommand<R> implements Command<R>
{
}
public interface CommandProcessor<C extends Command<?>>
{
public <R> R process(C<R> command);//this is my question... it's illegal to do, but you understand the idea behind it, right?
}
//constrain BasicCommandProcessor to commands that subclass BasicCommand
public class BasicCommandProcessor<C extends BasicCommand<?>> implements CommandProcessor<C>
{
//here, only subclasses of BasicCommand should be allowed as arguments but these
//BasicCommand object should be parameterized by R, like so: BasicCommand<R>
//so the method signature should really be
// public <R> R process(BasicCommand<R> command)
//which would break the inheritance if the interface's method signature was instead:
// public <R> R process(Command<R> command);
//I really hope this fully illustrates my conundrum
public <R> R process(C<R> command)
{
return command.execute();
}
}
public class CommandContext
{
public static void main(String... args)
{
BasicCommandProcessor<BasicCommand<?>> bcp = new BasicCommandProcessor<BasicCommand<?>>();
String textResult = bcp.execute(new BasicCommand<String>()
{
public String execute()
{
return "result";
}
});
Long numericResult = bcp.execute(new BasicCommand<Long>()
{
public Long execute()
{
return 123L;
}
});
}
}
Básicamente, quiero que el método de "proceso" genérico para dictar el tipo de parámetro genérico del objeto Command. El objetivo es poder restringir diferentes implementaciones de CommandProcessor a ciertas clases que implementan la interfaz Command y al mismo tiempo poder invocar el método de proceso de cualquier clase que implemente la interfaz CommandProcessor y hacer que devuelva el objeto de tipo especificado por el Objeto de comando parametarizado. No estoy seguro si mi explicación es lo suficientemente clara, así que por favor avíseme si se necesita una explicación más detallada. Supongo que la pregunta es "¿Sería posible hacer esto?" Si la respuesta es "No", cuál sería la mejor solución (pensé en una pareja sola, pero me gustaría algunas ideas nuevas)
¿No debería 'BasicCommand' implementar' Command'? –
Touche, arreglado. Gracias por atrapar eso! – Andrey