Java - conflicting interface parameters
I am working on a project that involves reading in lines from a string / stream. Within my project, I tried to create something along these lines:
-
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>;
However, I am getting an error with GenericThingDeserialiser
because there is a conflict between
-
ThingDeserialiser
implementationIterable<Thing>
and -
GenericThingDeserialiser
trying to implementIterable<T>
.
I can create a setting like this in C#
, why can't I do it in Java
?
Is there a way to get around this?
I also considered deleting ThingDeserialiser
in the hopes that ShinyThingDeserialiser
u SpecialThingDeserialiser
might be protected from GenericThingDeserialiser<Thing>
, but as expected, won't work.
I have a different idea with interfaces, but I would like to stop and ask for advice before continuing.
If not obvious, the general idea is that objects Thing
are fetched from strings / streams based on reasonably trivial patterns.
source to share
I would definitely suggest uninstalling ThingDeserialiser. You say you want to pass ShinyThingDeserialiser and SpecialThingDeserializer to GenericThingDeserialiser <Thing>, but that won't work. You should be able to pass these to GenericThingDeserialiser <? expands Thing>. Does it help?
source to share
I can create a setup like this in C #, why can't I do it in Java?
Because generics in Java are not covariant.
That is, even if you have types A
and B
, while B
extends A
, the class Foo<B>
will not be a subtype Foo<A>
. Due to the erasure of the styles at runtime, both options will be Foo
.
As said, you really should get rid of ThingDeserialiser
here and just be done with GenericThingDeserializer<T extends Thing> implements Iterable<T>
. Then you can create, say MyThingDeserialiser implements GenericThingDeserialiser<MyThing>
.
source to share