Jason S
Jason S

Reputation: 189646

generic interface: list of something specific

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

Answers (3)

RobbieV
RobbieV

Reputation: 444

Keep in mind that implementing interfaces like java.util.List correctly is hard; so ask yourself all of these questions:

  • Can I use java.util.List "as is", do I need to add/remove functionality?
  • Is there something simpler I could implement, like Iterable<T>?
  • Can I use composition? (vs. inheritance)
  • Can I find the newly desired functionality in existing libraries like Google Collections?
  • If I need to add/remove functionality, is it worth the added complexity?

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

Michael Myers
Michael Myers

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

newacct
newacct

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

Related Questions