2016-07-18 3 views
0

У меня есть класс, представляющий службу поставщика, и все их службы имеют аутентификацию и метод выполнения.Java - Обработка дженериков с наследованием

Я начал изучать абстрактный класс, который представляет это, как показано ниже. Вещь каждой из их услуг требует другого объекта запроса, поэтому я думал об использовании дженериков. Проблема в том, что если вы используете его, я не могу обрабатывать специфику каждого объекта запроса. Каждый ребенок должен использовать некоторые методы из этого типа.

1) Должен ли я попытаться это сделать, я пытаюсь или удаляю этот метод executeRequest из абстрактного класса, и каждый подкласс реализует его с правильным типом?

2) Я всегда слышу «предпочитаю композицию над наследованием». Должен ли я переместить executeRequest на интерфейс?

Заранее благодарен!

public abstract class VendorService { 

    private final VendorInitialization VendorInitialization; 

    //a bean with some auth params 
    public VendorService(VendorInitialization VendorInitialization) { 
     this.VendorInitialization = VendorInitialization; 
    } 

    protected abstract <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest; 

    protected abstract <T, P> P executeRequest(T requestObject); 
} 


public class VendorServiceAllocation extends VendorService { 

    public VendorServiceAllocation(VendorInitialization VendorInitialization) { 
     super(VendorInitialization); 
    } 

    @Override 
    protected <T> boolean validateRequest(T requestObject) throws VendorServiceBadRequest { 

     //List<BeanAllocation> requestObject = new Arraylist<>(); //I was using like this before 

     //TODO: how to handle it as list of on this specific case? 
     if (requestObject == null || requestObject.size() == 0) { 
      throw new VendorServiceBadRequest(String.format("The list must have at least one element")); 
     } 

     //TODO: requestObject.get(0).getMySpecificFieldFromBeanAllocation will not work 

     //some checks 
     return true; 
    } 

    @Override 
    protected <T, P> P executeRequest(T requestObject) { 
     //executes and return a list of objects specific to this class 
     return new List<BeanAllocationResponse>(); 
    } 
} 

Edit, для уточнения: В дочернем классе VendorServiceAllocation, мне нужно использовать некоторые методы, которые являются специфическими для данного типа.

т.д .: Внутри executeRequest, мне нужно позвонить requestObject.customFunctionFromChild()

+1

Я думаю, что ваша реализация абстрактного просто отлично; вам просто нужно убедиться, что функциональность, которую вы абстрактно предоставляете родительскому родителю, полезна для всех детей. –

+0

Думая, как 'executeRequest', все дети будут использовать его. Но если я думаю об объектах, каждый ребенок получит другой объект. Тогда я должен удалить его из абстракции? Или вы думаете, что я мог бы использовать дженерики? –

+3

вы делаете абстрактные методы обобщенными, в то время как класс не является, вместо этого генерируйте общий класс, тогда у вас может быть подкласс Class1, который наследует «Parent » и другой, который наследует «Parent » (целые и строковые примеры для иллюстрации) – niceman

ответ

1

Я думаю niceman ударил гвоздь по голове, хотя я не совсем уверен, что вы просите. например.

abstract class Service<T,P>{ 
    abstract public P processRequest(T t); 
} 

Тогда вы можете реализовать его одним из двух способов.

class StringService extends Service<String, String>{ 
    public String processRequest(String t){ 
     return t; 
    } 
} 

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

class OtherService<T> extends Service<T, String>{ 
    public String processRequest(T t){ 
     return t.toString(); 
    } 
} 

Где вы могли бы использовать его в качестве,

OtherService<Integer> is = new OtherService<>(); 
+0

это именно то, что я хотел. Я поддержал ваш ответ, но я попросил @niceman отправить ответ в качестве ответа он ответил первым .. надеюсь, вы понимаете! :) –