我正在开发一个涉及从字符串/流中读取结构的项目。 作为我设计的一部分,我试图沿着这些方向创造一些东西:
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
,希望ShinyThingDeserialiser
和SpecialThingDeserialiser
都可以投放到GenericThingDeserialiser<Thing>
,但正如预期的那样,它不会起作用。
我有另一个涉及接口的想法,但我想在继续之前停下来征求意见。
如果不明显,一般的想法是基于合理的琐碎模式从字符串/流中检索Thing
个对象。
答案 0 :(得分:4)
我能够在C#中创建这样的设置,为什么我无法在Java中执行此操作?
因为Java中的泛型不是协变的。
也就是说,即使您有类型A
和B
,B
延伸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;。这有帮助吗?