-3

I can't figure out how to write this correctly so it will not generate compiler errors:

class AnElement implements IElement { ... }

protected ArrayList<AnElement> someElements() {
    ...
}

protected ArrayList<IElement> elements() {
    return (ArrayList<IElement>) someElements(); // this doesn't work...
    // return someElements();                    // ... neither does this
}

What's the correct way to do this?

ycomp
  • 8,316
  • 19
  • 57
  • 95
  • hmm.. just realized the word Element is not the best for this example, it's just I had that as part of my actual class I use in my real code – ycomp Sep 28 '15 at 23:44
  • Define _doesn't work_. What compiler errors? What do you think they mean? – Sotirios Delimanolis Sep 28 '15 at 23:46
  • "Incompatible Types" error in the IDE. IDE has a big red line under the code. Required: ArrayList, Found: ArrayList – ycomp Sep 28 '15 at 23:47
  • @SotiriosDelimanolis: You're right, that one's a better dupe-target. I'll reopen this, and you can reclose as a dupe of that? – ruakh Sep 28 '15 at 23:53
  • Just for the future though: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p – Sotirios Delimanolis Sep 28 '15 at 23:54

1 Answers1

3

Generics are invariant so you could do

protected List<? extends IElement> elements() {
    return someElements(); 
}
Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • Or even better, code to the interface and do `protected List someElements()` instead. – Mick Mnemonic Sep 28 '15 at 23:50
  • @MickMnemonic that probably wouldnt compile as compiler cant be sure what exact implementation of `IElement` is returned from `someElements`.....:) – Reimeus Sep 28 '15 at 23:59
  • It does compile with the original code. – Mick Mnemonic Sep 29 '15 at 00:01
  • In general, you should avoid returning wildcard types and instead _return the most specific type_. The amazing Angelika Langer [explains why](http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ303). (Might not make that much of a difference when `IElement` is an `interface`, but still.) – Mick Mnemonic Sep 29 '15 at 00:17
  • actually yes the base is an interface IElement.. but then there is AnElement implements IElement and ChildOfAnElement extends AnElement... _and more_. I simplified things in the original post. Basically all objects are guaranteed to be of IElement ... – ycomp Sep 29 '15 at 12:47