2013-12-19 7 views
0

У меня есть абстрактный суперсервис, который должен выполнять некоторую общую логику. Несколько сервисов реализуют этот суперсервис. Я выбрал ServiceImpl на основе условия и хочу назначить его абстрактному типу, чтобы позже запустить общую логику.Как создать общие методы, которые принимают любой параметр типа?

Что не так в следующем? Я хотел бы передать в метод process() любой объект, который имеет/extends BaseResponse, например FirstResponse в моем примере.

//superservice 
abstract class AbstractService<T extends BaseResponse> { 
    public void process(T t) { 
     //execute logic that is common to a BaseResponse 
    } 
} 

//implementations 
class FirstService extends AbstractService<FirstResponse extends BaseResponse> { 
} 

//usage 
AbstractService<? extends BaseResponse> myservice = new FirstService(); //chose by condition 
myservice.process(new FirstResponse()); //ERROR 

результат:

The method build(capture#2-of ? extends BaseResponse) 
in the type AbstractService<capture#2-of ? extends BaseResponse> is not applicable for the arguments (FirstResponse) 
+0

ли 'FirstService' работа с' BaseResponse' или любой подкласс «BaseResponse» или конкретного подкласса? – Bohemian

+0

Я думаю 'AbstractService myservice = new FirstService() 'должен делать трюк не так? –

+0

'FirstService' будет работать с' BaseResponse'; '? super' позволит вызвать 'myservice.process()', но я тогда не могу назначить 'FirstService' больше ... – membersound

ответ

3
//execute logic that is common to a BaseResponse 

Если это так, то гибкость, обеспечиваемая по наследству достаточно, вы на самом деле не нужны дженерики.

public void process(BaseResponse t) { 
    // ... 
} 

Причина ошибки заключается в том, что компилятор Java знает myservice является AbstractService<? extends BaseResponse>. Это не является неправильным переназначить myservice к другому подклассу позже:

AbstractService<? extends BaseResponse> myservice = new FirstService(); 
myservice = new SecondService(); // <---------- should be ok 
myservice.process(new FirstResponse()); // <--- making this bad 

, вероятно, будет истинной ошибкой. Если вам нужно сохранить интерфейс process(T), вы должны изменить тип myservice тогда:

FirstService myservice = new FirstService(); 
myservice.process(new FirstResponse()); 
2

Вы можете сделать это с дженериков, как это:

abstract class AbstractService<T extends BaseResponse> { 
    public void process(T t) { 
     //execute logic that is common to a BaseResponse 
    } 
} 

//implementations 
class FirstService extends AbstractService<FirstResponse> { 
    @Override 
    public void process(FirstResponse firstResponse) { 
     super.process(firstResponse); 
     ... 
    } 
} 

public static void main(String[] args) { 
    //usage 
    AbstractService<FirstResponse> myservice = new FirstService(); 
    myservice.process(new FirstResponse()); 
} 
+0

Но с этим я, например, не мог написать:' AbstractService myservice = new SecondService() ; 'if' class SecondService '. Я хотел бы выбрать службу на основе условия, а затем запустить 'myservice.process' независимо от службы. – membersound

+0

Непроверенный актер - это простой способ, я могу думать о 'AbstractService myservice = (AbstractService) новом FirstService();', тем не менее, обескураженный. –

Смежные вопросы