2017-02-10 2 views
0

У меня есть следующий код (упрощенный, чтобы показать суть проблемы):Интерфейс распространения реализации в Java дженерик

public interface IElement {} 


public interface IDataSet<E extends IElement> {} 


public interface IPropertyTranslator<D extends IDataSet<? super E>, E extends IElement> {} 


public interface IElementTranslator<D extends IDataSet<?>> {} 


public class AnimalElement implements IElement {} 


public class AnimalDataSet implements IDataSet<AnimalElement> {} 


public class AnimalPropertyTranslator implements IPropertyTranslator<AnimalDataSet, AnimalElement> {} 


public class UniversalPropertyTranslator implements IPropertyTranslator<IDataSet<IElement>, IElement> {} 


public class ElementTranslator<D extends IDataSet<? super E>, E extends IElement> implements IElementTranslator<D> { 

    public Collection<IPropertyTranslator<? super D, ? super E>> propertyTranslators = new HashSet<>(); 

} 


public class Demo { 

    public static void demo() { 
     ElementTranslator<AnimalDataSet, AnimalElement> animalElementTranslator = new ElementTranslator<>(); 
     animalElementTranslator.propertyTranslators.add(new AnimalPropertyTranslator()); 
     animalElementTranslator.propertyTranslators.add(new UniversalPropertyTranslator()); 
    } 

} 

К сожалению, последняя строка демонстрационного метода дает следующее сообщение об ошибке: The method add(IPropertyTranslator<? super AnimalDataSet,? super AnimalElement>) in the type Collection<IPropertyTranslator<? super AnimalDataSet,? super AnimalElement>> is not applicable for the arguments (UniversalPropertyTranslator). Через случайные испытания я обнаружил, что проблема, вероятно, связана с выражением <D extends IDataSet<? super E>, E extends IElement>, хотя я до сих пор не знаю, как это исправить.

В то же время следующие variantion кода отлично работает:

public interface IDataSet {} 


public interface IPropertyTranslator<D extends IDataSet> {} 


public interface IElementTranslator<D extends IDataSet> {} 


public class AnimalDataSet implements IDataSet {} 


public class AnimalPropertyTranslator implements IPropertyTranslator<AnimalDataSet> {} 


public class UniversalPropertyTranslator implements IPropertyTranslator<IDataSet> {} 


public class ElementTranslator<D extends IDataSet> implements IElementTranslator<D> { 

    public Collection<IPropertyTranslator<? super D>> propertyTranslators = new HashSet<>(); 

} 


public class Demo { 

    public static void demo() { 
     ElementTranslator<AnimalDataSet> animalElementTranslator = new ElementTranslator<>(); 
     animalElementTranslator.propertyTranslators.add(new AnimalPropertyTranslator()); 
     animalElementTranslator.propertyTranslators.add(new UniversalPropertyTranslator()); 
    } 

} 

Я не понимаю, почему вторая общая часть интерфейса заставляет код вести себя по-разному.

+0

Возможный дубликат [Разница между и в Java] (http://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java) –

+0

Возможно, но Я прочитал документацию, расписав разницу между супер и расширением, и использовал ее в интерфейсах, как я и предполагал, чтобы они функционировали. Проблема заключается в следующем: почему 'Collection > 'не принимает' IPropertyTranslator , IElement> '? –

ответ

0

Решение немного связано с правилом «Продюсер продляет, потребитель супер». В коде проблемы необходимо изменить следующие заголовки ниже:

public interface IPropertyTranslator<D extends IDataSet<? extends E>, E extends IElement> {} 

public class UniversalPropertyTranslator implements IPropertyTranslator<IDataSet<? extends IElement>, IElement> {} 

и все будет работать нормально.

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