tags:

views:

136

answers:

5

Suppose I have a class that implements an interface:

public class A implements IB

and I have a List<A> that I would like to reference to: List<? implements IB> list. So that I can code: for (IB item : list) etc.

Can it be done somehow in Java? There is no <? implements ...> possibility. What am I missing?

+1  A: 

Well, you could declare it a List<IA>.

To build upon this further, List can store any objects that implement IA in it. The catch is that, when retrieving them back out, you don't know the original class without doing a .getClass() on it.

Example:

List<IA> list = new ArrayList<IA>();
// code to populate list here
for (IA item : list) {
    item.iaMethod();
}
R. Bemrose
+6  A: 

Use extends:

public void someMethod(List<? extends IB> list) {
  for (IB e : list) {
    // Perform some processing on each element.
  }
}

public void anotherMethod() {
  List<A> list = new ArrayList<A>();
  someMethod(list);
}

More information can be found at The Java Tutorials which has a comprehensive lesson on Generics.

In particular, the section on wildcards explains how to use the ? with super and extends to specify a parameter to be one that is a superclass or subclass of a given class.

coobird
I recommend also the session from Joshua Bloch from JavaOne this year for more info. Really cleared it up for me: http://developers.sun.com/learning/javaoneonline/sessions/2009/pdf/TS-5217.pdf
amischiefr
Thanks for the answer.
Gerard
+1  A: 

What about:

List<? extends IA> list;
OscarRyz
A: 

You can do it with extends:

List<? extends IA> list
bruno conde
A: 

If you meant that class A implements IA, rather than IB, then your code should be just fine saying

for (A item : list) {
    // handle item as if it is an IA
}

since all As are, by definition IAs.

Meanwhile, there is no wildcard for <? implements C>. There is <? extends C>, and C can be an interface or a class; however, this isn't necessary for what you seem to be trying to do.

If you want expressly to say for (IA item : list) because you're not guaranteeing that items in that list are As, but are guaranteeing that they are IAs, then I think you have a slight problem (I can't tell for sure, since you didn't say where this list processing code is located). A List<A> is not a List<IA> by definition; if you're building a List<A> and then passing it to a method that expects a List<IA>, you'll get a compile time error. You can, however, create a List<IA> and fill it with As. The reason for this is explained in Java's tutorial on generics.

Paul Brinkley
What was I thinking? It works perfectly well because in <? extends C> C can also be an interface. I thought 'extends' <=> inheritance.
Gerard