My question is not easy to explain using words, fortunately it's not too difficult to demonstrate. So, bear with me:
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>
{
}
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 implements CommandProcessor<C extends BasicCommand<?>>
{
//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 bcp = new BasicCommandProcessor();
String textResult = bcp.execute(new BasicCommand<String>()
{
public String execute()
{
return "result";
}
});
Long numericResult = bcp.execute(new BasicCommand<Long>()
{
public Long execute()
{
return 123L;
}
});
}
}
Basically, I want the generic "process" method to dictate the type of generic parameter of the Command object. The goal is to be able to restrict different implementations of CommandProcessor to certain classes that implement Command interface and at the same time to able to call the process method of any class that implements the CommandProcessor interface and have it return the object of type specified by the parametarized Command object. I'm not sure if my explanation is clear enough, so please let me know if further explanation is needed. I guess, the question is "Would this be possible to do, at all?" If the answer is "No" what would be the best work-around (I thought of a couple on my own, but I'd like some fresh ideas)