Если дизайн контракта заключается в том, что каждая служба может обрабатывать любой тип запроса, то ваша реализация MyService, которая принимает только MyRequest (и прерывается, если передаются другие типы запросов), неверна.
Если план контракта таков, что подклассы Service и Request отображаются друг на друга, например, MyService может (и должен) только обрабатывать MyRequest, тогда вам нужно будет изменить интерфейс Service. В противном случае текущий интерфейс, как написано в вопросе, не выполняет то, что в нем описано. Один из способов исправить это параметризовать интерфейс Сервиса:
interface Service<R> {
void process(R request);
}
тогда ваш конкретный MyService будет
public class MyService implements Service<MyRequest> {
public void process (MyRequest r) {/*blah*/}
}
Пример этого можно увидеть в действии в JDK - интерфейс Comparator делает именно это, по той же причине. http://java.sun.com/javase/6/docs/api/java/util/Comparator.html
Я не понимаю, почему вы это сделаете, но если вы все еще хотите ограничить иерархию MyRequest запросом, вы можете поменять Service<R>
на Service<R extends Request>
edit: очевидно, что это не работает в 1.4, поэтому, чтобы сделать то же самое [1], вам нужно будет использовать шаблон посетителя. Это уродливее, но 1,4 уродливо =)
interface Service {
void process(Request visitor);
}
interface RequestVisitor {
void visitMyRequest(MyService service);
void visitYourRequest(YourService service);
void visitTheOtherRequest(TheOtherService service);
}
interface Request extends RequestVisitor { /* and any extra methods required for request*/ }
public class MyService implements Service {
public process(Request r) {r.visitMyRequest(this);}
public void doSpecialMyProcessing(MyRequest request) { /* your code using MyRequest*/ }
}
public class YourService implements Service {
public process(Request r) {r.visitYourRequest(this);}
public void doSpecialYourProcessing(YourRequest request) { /* your code using YourRequest */ }
}
public class MyRequest implements Request {
void visitMyRequest(MyService service) {
service.doSpecialMyProcessing(this);
}
void visitYourRequest(YourService service) {
throw new UnsupportedOperation("Cannot call visitYourRequest in MyRequest!");
}
void visitTheOtherRequest(TheOtherService service) {
throw new UnsupportedOperation("Cannot call visitTheOtherRequest in MyRequest!");
}
}
public class YourRequest implements Request {
void visitMyRequest(MyService service) {
throw new UnsupportedOperation("Cannot call visitMyRequest in YourRequest !");
}
void visitYourRequest(YourService service) {
service. doSpecialYourProcessing(this);
}
void visitTheOtherRequest(TheOtherService service) {
throw new UnsupportedOperation("Cannot call visitTheOtherRequest in YourRequest !");
}
}
[1] на самом деле это не то же самое , потому что теперь вам нужно будет написать метод для каждого подтипа запроса. В версии 1.4 вам нужно будет разыгрывать и делать instanceof и т. Д., Чтобы добиться того, что 1.5 может делать с генериками.