Java - 冲突的接口类型参数

时间:2014-10-28 12:30:27

标签: java

我正在开发一个涉及从字符串/流中读取结构的项目。 作为我设计的一部分,我试图沿着这些方向创造一些东西:

  • public class Thing;
  • public class SpecialThing extends Thing;
  • public class ShinyThing extends Thing;
  • public abstract class ThingDeserialiser implements Iterable<Thing>;
  • public abstract class GenericThingDeserialiser<T extends Thing> extends ThingDeserialiser implements Iterable<T>;
  • public class SpecialThingDeserialiser extends GenericThingDeserialiser<SpecialThing>;
  • public class ShinyThingDeserialiser extends GenericThingDeserialiser<ShinyThing>;

但是我在GenericThingDeserialiser收到错误,因为

之间存在冲突
  • ThingDeserialiser实施Iterable<Thing>
  • GenericThingDeserialiser尝试实施Iterable<T>

我可以在C#中创建这样的设置,为什么我无法在Java中执行此操作?

有什么方法可以解决这个问题吗?


我还考虑删除ThingDeserialiser,希望ShinyThingDeserialiserSpecialThingDeserialiser都可以投放到GenericThingDeserialiser<Thing>,但正如预期的那样,它不会起作用。

我有另一个涉及接口的想法,但我想在继续之前停下来征求意见。

如果不明显,一般的想法是基于合理的琐碎模式从字符串/流中检索Thing个对象。

2 个答案:

答案 0 :(得分:4)

  

我能够在C#中创建这样的设置,为什么我无法在Java中执行此操作?

因为Java中的泛型不是协变的。

也就是说,即使您有类型ABB延伸A,类Foo<B>也不会是{{}的子类型1}}。由于类型擦除,在运行时,两者都将是Foo<A>

正如已经建议的那样,你应该在这里摆脱Foo,而只是使用ThingDeserialiser。然后,您可以创建GenericThingDeserializer<T extends Thing> implements Iterable<T>

答案 1 :(得分:2)

我肯定会建议删除ThingDeserialiser。你说你想将ShinyThingDeserialiser和SpecialThingDeserializer转换为GenericThingDeserialiser&lt; Thing&gt;,但这不起作用。你应该能够将它们转换为GenericThingDeserialiser&lt;?延伸事物&gt;。这有帮助吗?