0

It would be of great help, if someone can point out the problem and possible explanation here.

class Parent{}    
public class ChildClass extends Parent{ 
  /*Main class*/    
  public static void main(String[] args) {  

      ArrayList<ChildClass> a3 = new ArrayList<ChildClass>();   
      foo(a3);      
    }
  /*another function*/
  static void foo(ArrayList<Parent> obj) {      
}

This throws the following compilation error.

The method foo(ArrayList<Parent>) in the type ChildClass is not applicable for the arguments (ArrayList<ChildClass>)

The rule of Polymorphism should allow me to do it. Right? After all the ChildClass IS-A Parent. What seems to be the problem?

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
Ekta
  • 338
  • 2
  • 9
  • 26

1 Answers1

5

ChildClass is-a Parent, but ArrayList<ChildClass> is-not-an ArrayList<Parent>. If you consider this code, it shoud be clear why:

ArrayList<ChildClass> a3 = new ArrayList<>();
foo(a3);
ChildClass c = a3.get(0);

...

static void foo(ArrayList<Parent> obj) {
   obj.add(new Parent());
}

If the above code happened to compile without error, it would be type-unsafe and actually fail at runtime with ClassCastException.

So, for the relation "ArrayList<ChildClass> is-a ArrayList<Parent>" to actually make sense, these two facts would have to be simultaneously true:

  1. ChildClass is-a Parent;
  2. Parent is-a ChildClass.

In general, that can be true only if ChildClass is the same type as Parent, under a different name. So we arrive at the real rule Java applies, which is called type invariance: it neither holds that ArrayList<ChildClass> is-an ArrayList<Parent>, nor that ArrayList<Parent> is-an ArrayList<ChildClass>.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • So the overall point is that ArrayList will only take parent and nothing else and same is true for ArrayList. That's because when we pop up the values, it doesn't know which object is being extracted. Right? P.S. The above code also does not compile for me in my eclipse. Anyways I got the point. – Ekta Sep 17 '14 at 08:29
  • You can add child to `ArrayList`, but you can't pass an `ArrayList` to a method which expects `ArrayList`. As for compilation, these are two snippets of code and don't compile as-is. You must include the first part into a method (such as `main`). – Marko Topolnik Sep 17 '14 at 08:30