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
  • 398,947
  • 96
  • 818
  • 769
Chet
  • 1,209
  • 1
  • 11
  • 29

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
  • 26,764
  • 16
  • 85
  • 118
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
  • 125,917
  • 54
  • 300
  • 447
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
  • 268,207
  • 37
  • 334
  • 440
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,436
  • 13
  • 85
  • 118