2015-01-27 7 views
1

Я столкнулся с одной проблемой с общей реализацией. Ниже приведен код:Проблема с общим интерфейсом

public interface Response<S, T> { 

public void response(S data, T... arg); 
} 

public class CustomerDetail<XYZ, PQR> implements Response<XYZ, PQR> { 
    @Override 
    public void response(XYZ data, PQR... args) { 
    PQR request = args[0]; 
    Map reportMap = data.any(); 
    //do something 
    } 
} 


public class EmployeeDetail<ABC, DEF> implements Response<ABC, DEF> { 
    @Override 
    public void response(ABC data, DEF... args) { 
    List reportList = data.getDetails(); 
    //do something 
    } 
} 

Кроме того, класс XYZ, ABC выглядит, как показано ниже:

public class XYZ { 
    public Map any() { 
    //do something 
    return mapObject; 
    } 
} 

public class ABC { 
    public List getDetails() { 
    //do something 
    return listObject; 
    } 
} 

Во время компиляции, я получаю ошибку компиляции:

cannot find method any(); 
cannot find the method getDetails(); 

Ранее я пытался с этот код, и он работал нормально:

public class CustomerDetail<S, T> implements Response<S, T> { 
    @Override 
    public void response(S data, T... args) { 
    PQR request = (PQR)args[0]; 
    Map reportMap = ((XYZ)data).any(); 
    //do something 
    } 
} 


public class EmployeeDetail<S, T> implements Response<S, T> { 
    @Override 
    public void response(S data, T... args) { 
    List reportList = ((ABC)data).getDetails(); 
    //do something 
    } 
} 

Но я не хочу, чтобы типизация общих переменных. Поэтому я следовал вышеприведенному подходу. Я пытался следовать за link Любая идея, где я делаю ошибку. Благодаря

+0

И какая строка кода была ошибкой компиляции? –

+0

Возможный дубликат [Java-класс с конкретным типом как параметр] (http://stackoverflow.com/questions/20294095/java-class-with-concrete-type-as-parameter) – Joe

+0

Внутри 'EmployeeDetail' и' CustomerDetail', 'XYZ' и' DEF' * не означают классы, они означают параметры типа. Вот почему это плохая идея дать одно и то же имя для разных вещей. – immibis

ответ

3

Вы близки, но вы затеняете классы с общими типами.

Эта декларация (с лишним public удален):

public interface Response<S, T> { 
    void response(S data, T... arg); 
} 

принимает любых типов S и T, так что class:

public class CustomerDetail<XYZ, PQR> implements Response<XYZ, PQR> { 
    @Override 
    public void response(XYZ data, PQR... args) { 
    PQR request = args[0]; 
    Map reportMap = data.any(); 
    //do something 
    } 
} 

Просто переопределяет общий тип переменныхS -> XYZ и T -> ABC. Здесь вы не указали конкретные типы, вы просто определили общие переменные типа, которые имеют то же имя, что и ваши классы.

Если вы хотите class расширить общий тип конкретных, он не должен иметь определения типов:

public class CustomerDetail implements Response<XYZ, PQR> { 
    @Override 
    public void response(XYZ data, PQR... args) { 
    PQR request = args[0]; 
    Map reportMap = data.any(); 
    //do something 
    } 
} 

В качестве примечания, как вы играете с обобщениями, вы должны знать, что определение от List - List<E>, а определение Map - Map<K, V> - они также являются общими. Не используйте rawtypes.

0

Изменение:

public class CustomerDetail<XYZ, PQR> implements Response<XYZ, PQR> 

To:

public class CustomerDetail implements Response<XYZ, PQR> 

И изменение:

public class EmployeeDetail<ABC, DEF> implements Response<ABC, DEF> 

к:

public class EmployeeDetail implements Response<ABC, DEF> 
2

Ваши классы, реализующие интерфейсы, не являются классами дженериков. Таким образом, вы не должны предоставлять параметры:

public class EmployeeDetail<ABC, DEF> implements Response<ABC, DEF> { 

Это делает общий класс EmployeeDetail с двумя параметрами ABC и DEF. Вы хотите заполнить параметры класса Response.

Вместо этого вы должны сделать следующее:

public class EmployeeDetail implements Response<ABC, DEF> { 

Это указывает на то, что EmployeeDetail заполняет параметры интерфейса Response.

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