Java inheritance with parameterized Lists
Asked Answered
F

3

2

I have a strange problem with inheritance and I don't understand why it should not work:

public interface A {  }

public interface B extends A {}


public class C {
void test() {
    ArrayList<A> foo = new ArrayList<B>();
    }
}

But compiling gives me the following error

Type mismatch: cannot convert from ArrayList<B> to ArrayList<A> C.java /bla/src/de/plai/test line 8 Java Problem

Firooc answered 10/4, 2011 at 13:50 Comment(1)
you should probably grab this Generics tutorial.Sew
L
4
ArrayList<? extends A> foo = new ArrayList<B>();

A List of A is not the same that a List of B because you could not guarantee consistency of contents in the list.

Namely, if it were possible you could insert an item of type A in a list that was instantiated only to contain B elements.

Of course the above declaration will prevent you from writing any elements into the list. This is a read-only declaration.

Also it is a good OOP principle to declare the variables as interfaces, not implementations:

List<? extends A> foo = new ArrayList<B>();
Lalise answered 10/4, 2011 at 13:53 Comment(0)
H
7

It may seem counterintuitive at first, but even if class B is a subclass of A, a List<B> is not a subclass of List<A>. I gave a more detailed explanation and example in this earlier answer to a similar post. See also this other answer for a link to the respective item in Effective Java 2nd Edition.

The solution to this problem is using wildcards. Thus you should declare your list as

List<? extends A> foo = new ArrayList<B>();
Haas answered 10/4, 2011 at 13:52 Comment(0)
L
4
ArrayList<? extends A> foo = new ArrayList<B>();

A List of A is not the same that a List of B because you could not guarantee consistency of contents in the list.

Namely, if it were possible you could insert an item of type A in a list that was instantiated only to contain B elements.

Of course the above declaration will prevent you from writing any elements into the list. This is a read-only declaration.

Also it is a good OOP principle to declare the variables as interfaces, not implementations:

List<? extends A> foo = new ArrayList<B>();
Lalise answered 10/4, 2011 at 13:53 Comment(0)
U
1

Was just above to to post the same :) well nevertheless.. the answer is same this should work for you.

ArrayList<? extends A> foo = new ArrayList<B>();
Unsupportable answered 10/4, 2011 at 14:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.