5

I have a simple POJO named "Father" and another one named "Son" which extends "Father", the simplest class inheritance example.

Now I have a List<Son> and I need to cast it to a List<Father>.

How can I do?

EDIT

Sorry for the bad naming, I didn't explain myself. Person and Employee would have been a better example. Or Product and Computer, too.

Fabio B.
  • 9,138
  • 25
  • 105
  • 177
  • 1
    Why would you want to cast "down"? A `Son` is a `Father`, so it can do anything a `Father` can do... – Lukas Knuth Feb 27 '13 at 12:12
  • 4
    [You can't](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicit) => you will need to copy the content. – assylias Feb 27 '13 at 12:12
  • 3
    There is a logical flaw here. Not every `Son` is a `Father`. However it can be true in a parallel universe. – Adam Arold Feb 27 '13 at 12:14
  • 4
    A `Son` is a `Father`? A son **has-a** father. The real world example cries for composition instead of inheritance! – Andreas Dolk Feb 27 '13 at 12:15
  • Inheritance in object oriented programming has a completely different meaning than in biology. In OO, inheritance means **specialization**: a subclass *is a specialized version of* a superclass. Using names such as `Father` and `Son` for the classes confuses it with the biological meaning of inheritance. – Jesper Feb 27 '13 at 12:26
  • @Andreas_D obviously... the right example would be "Person" and "SalesPerson" – Fabio B. Feb 27 '13 at 13:21

4 Answers4

3

You can't use a cast here* as commented above. You could write a small helper method to do the conversion (i.e.the copy):

private static List<Father> getListFather(List<? extends Father> list) {
    return new ArrayList<> (list);
}

* Actually you can - cf the other answer: List<Father> listFather = (List<Father>) (List<? extends Father>) listSons;

assylias
  • 321,522
  • 82
  • 660
  • 783
3

Assume for a moment you could do that with a cast, it would lead to the following problem:

List<Son> ls = ...;
List<Father> lf = (List<Son>) ls;
lf.add(new Father());

Both ls and lf point to the same instance so you have just added a Father object into a list of Sons.

Henry
  • 42,982
  • 7
  • 68
  • 84
3

2 suggestions:

Have an Interface, say Person, that Father (and thus Son) implements. Use List<Person> for both.

Create a new List<Father> with the collection Constructor, e.g. List<Father> fathers = new ArrayList<Father>(sons);

frIT
  • 3,213
  • 1
  • 18
  • 22
2

This seems to work:

static class Father {};
static class Son extends Father{};

public void test() {
  List<Son> sons = new ArrayList<>();
  // Not allowed.
  //List<Father> sons2 = (List<Father>)sons;
  // Two step.
  List<? extends Father> sons3 = sons;
  List<Father> sons4 = (List<Father>)sons3;
  // Direct.
  List<Father> sons5 = (List<Father>)((List<? extends Father>)sons);
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213