Reputation: 13499
I have a class B which extends A. A stores a list of AItem and B stores a list of BItem
In 'A' I have an ArrayList which uses [? extends AItem] .
I assume this means that I can use this ArrayList for objects of any type that extends AItem.
So in my B class I have a method add(..) which adds a BItem to the items.
I assumed this would work because the items arrayList can hold a list of any object that extends from AItem.
import java.util.ArrayList;
class A {
public ArrayList<? extends AItem> items;
}
public class B extends A{
public void add(BItem i) {
this.items.add(i); //compile error here
}
}
//items :
class AItem {}
class BItem extends AItem{}
How would I get this to work?
My compile error looks like this :
The method add(capture#2-of ? extends AItem) in the type ArrayList is not applicable for the arguments (BItem)
Upvotes: 3
Views: 77
Reputation: 1283
you can use
public ArrayList<? super AItem> items;
and you can add to the list now
but you will not be able to do
public class B extends A{
.....
public BItem getOne(int idx) {
return this.items.get(idx);
}
}
jvm doesn't know what will be actually in the list.
you can generify the A class
class A<T> {
public ArrayList<T> items;
}
then define your B class as
public class B extends A<BItem>{
public void add(BItem i) {
this.items.add(i);
}
}
Upvotes: 1
Reputation: 72844
You probably don't need to use generics here. Having the list of type AItem
in class A
should be fine (I would also declare it of type List
instead of ArrayList
for best practices):
class A {
public List<AItem> items;
}
class B extends A {
public void add(BItem i) {
this.items.add(i);
}
}
The problem with ? extends AItem
is that the compiler cannot guarantee that the actual type of the elements is AItem
or BItem
. It could be another subclass CItem
in which case the type safety is broken.
There is another approach to designing the class hierarchy with generics, in which you set the type parameter in the parent class and set it to the appropriate subclass (BItem
) in the extended class B
:
class A<T extends AItem> {
public ArrayList<T> items;
}
class B extends A<BItem>{
public void add(BItem i) {
this.items.add(i);
}
}
Upvotes: 6
Reputation: 5607
Try replacing extends
with super
import java.util.ArrayList;
class A {
public ArrayList<? super AItem> items;
}
public class B extends A{
public void add(BItem i) {
this.items.add(i); //compile error here
}
}
//items :
class AItem {}
class BItem extends AItem{}
You may find more details about the reason behind this behavior, here
Upvotes: 2