Gerard
Gerard

Reputation: 13397

java list of objects that all implement an interface

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?

Upvotes: 12

Views: 26744

Answers (6)

shizhen
shizhen

Reputation: 12583

An alternative that don't need to use List<? extends IB> list

public class A implements IB{

}

List<A> listOfConcreteClassA = new ArrayList<A>();

// convert to interface
List<IB> listOfInterfaceB = new ArrayList<IB>(listOfConcreteClassA)

Upvotes: 0

Paul Brinkley
Paul Brinkley

Reputation: 6353

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.

Upvotes: 3

Powerlord
Powerlord

Reputation: 88796

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

Upvotes: 1

bruno conde
bruno conde

Reputation: 48265

You can do it with extends:

List<? extends IA> list

Upvotes: 3

OscarRyz
OscarRyz

Reputation: 199215

What about:

List<? extends IA> list;

Upvotes: 8

coobird
coobird

Reputation: 160954

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.

Upvotes: 22

Related Questions