2

Why does this not work...

public ArrayList<Edge> getEdges() {

return A;

//A is an Arraylist of type 'Action'. Action implements Edge.

}

the interface Edge includes: public ArrayList getEdges();

even though this does.

public Edge getEdges() {

return B;

//B is an 'Action'. Action implements Edge.

}

the interface Edge includes: public Edge getEdges();

Thank You, Chet

skaffman
  • 390,936
  • 96
  • 800
  • 764
Chet
  • 1,189
  • 1
  • 10
  • 28

4 Answers4

7

Because while Edge is a subtype of Action, ArrayList<Action> is not a subtype of ArrayList<Edge>.

Use ArrayList<? extends Edge> instead.

You could take a look at this tutorial's 4. Wildcard section, although I'd suggest to just read through it, because it is really helpful.

zw324
  • 25,936
  • 16
  • 82
  • 114
2

This is because ArrayList<E> is not covariant on the type E. That is, you cannot substitute an instance of ArrayList<Derived> for ArrayList<Base> just because Derived inherits from Base.

Consider this case: String inherits from Object; however, if this meant you could use an ArrayList<String> as an ArrayList<Object> then the following code would be possible:

ArrayList<Object> list = new ArrayList<String>();
list.add(new Integer(5)); // Integer inherits from Object

The above can't work, because you can't add an Integer to an ArrayList<String>. If you could, then this could happen:

ArrayList<String> stringList = (ArrayList<String>)list;
String string = stringList.get(0); // Not a string!

As Ziyao has indicated, the correct way to implement this is to use the ? extends Edge syntax.

Community
  • 1
  • 1
Dan Tao
  • 122,418
  • 53
  • 286
  • 437
2

A banana is a fruit. A list of bananas is not a list of fruit.

Oherwise someone could construct a list of bananas, pass you a reference to a list of fruit, and you'd (correctly) insert an apple in it. The owner of the list of the bananas would be rightfully surprised.

Brian Agnew
  • 261,477
  • 36
  • 323
  • 432
0

Because the generic type must always be the same, not something that extends from it you can rewrite like this for it to work:

public ArrayList<? extends Edge> getEdges() {

return A;

//A is an Arraylist of type 'Action'. Action implements Edge.

}
Oscar Gomez
  • 18,248
  • 12
  • 81
  • 116