2017-02-10 71 views
0

我有以下代码(简化,以示出芯问题):接口实现传播

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

该解决方案与“Producer Extends,Consumer Super”规则略有关联。在问题代码中,需要将以下标题更改为以下标题:

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

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

并且一切都会正常工作。