Reputation: 189646
I want to define an interface MyList which is a list of interface MyThing. Part of the semantics of MyList is that its operations don't have any meaning on objects which do not implement the MyThing interface.
Is this the right declaration?
interface MyList<E extends MyThing> extends List<E> { ... }
edit: (part 2) Now I have another interface that returns a MyList as one of its methods.
// I'm defining this interface
// it looks like it needs a wildcard or template parameter
interface MyPlace {
MyList getThings();
}
// A sample implementation of this interface
class SpecificPlace<E extends MyThing> implements MyPlace {
MyList<E> getThings();
}
// maybe someone else wants to do the following
// it's a class that is specific to a MyNeatThing which is
// a subclass of MyThing
class SuperNeatoPlace<E extends MyNeatThing> implements MyPlace {
MyList<E> getThings();
// problem?
// this E makes the getThings() signature different, doesn't it?
}
Upvotes: 1
Views: 1396
Reputation: 444
Keep in mind that implementing interfaces like java.util.List correctly is hard; so ask yourself all of these questions:
That said, you could probably just use java.util.List for your example:
interface MyPlace<T extends MyThing> {
List<T> getThings();
}
class SpecificPlace implements MyPlace<MyThing> {
public List<MyThing> getThings() { return null; }
}
class SuperNeatoPlace implements MyPlace<MyNeatThing> {
public List<MyNeatThing> getThings() { return null; }
}
Upvotes: 0
Reputation: 191875
Yes, at least that is how EnumSet
does it.
public abstract class EnumSet<E extends Enum<E>>
extends AbstractSet<E>
Edit in answer to Part 2:
I'm not sure why the return type of getThings()
in the interface doesn't complain about raw types. I suspect that because of type erasure, warnings in interfaces would be useless even if they were there (there's no warning if you change the return type to List
, either).
For the second question, since MyNeatThing
extends MyThing
, E
is within its bounds. That's sort of the point of using the extends
bound in the generic parameter, isn't it?
Upvotes: 2
Reputation: 122429
For part 1, yes that looks right.
For your part 2, I suggest something like the following. The method returns a MyList
of something, which you don't know what it is (it is different for different implementations apparently), but you know it's a subtype of MyThing.
interface MyPlace {
MyList<? extends MyThing> getThings();
}
Upvotes: 1