views:

267

answers:

3

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?
}
+2  A: 

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?

Michael Myers
Hey wait a minute, what just happened with Lists being consumers and we were supposed to use super?
willcodejavaforfood
You can't use super in class type parameter declarations, which saves me from having to figure out the answer. ;)
Michael Myers
I think you're confusing 2 issues, although i'm not sure. I don't think you ever see SomeClass<T super Something>. You sometimes see SomeClass<? super Something> when that type is used to specify method arguments. http://www.ibm.com/developerworks/java/library/j-jtp07018.html
Jason S
Some JLS links: Type parameters (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.4 ) cannot use super. But parameterized types (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.5 ) can. So this is an entirely different scenario from the other question.
Michael Myers
re: "I'm not sure why the return type ... doesn't complain" -- my comment "it looks like it needs a parameter or wildcard" was me wondering about it, not the compiler complaining. I guess I'm still grasping the subtleties of generics...
Jason S
+1  A: 

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();
}
newacct
A: 

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; }
}
RobbieV
Oh, of course: I'm going to just delegate to an internal private list for most of these.
Jason S
The question isn't about the list aspect of it (replace List with Foo and my question stays the same) but about the generics aspect.
Jason S