Reputation: 2327
I have a class, say Animal
and a subclass Dog
. I want to have a List
named allAnimals
that can hold both Animal
objects and Dog
objects at the same time. Currently, it is set up as List<Animal> allAnimals
. I want to be able to perform two tasks:
Add supertypes and subtypes.
List<Dogs> dogs = new List<>();
...
allAnimals.addAll(dogs);
I want to be able to pass any subtype or supertype to a list as a parameter in a method.
public void foo(List<Animal> animals){...}
...
foo(allAnimals);
or
foo(dogs);
Is the above possible? wildcard <? extends Animal>
is giving an error in this case since foo
is both putting things in the list and taking them out. Do I need to make Animal
class abstract in order to achieve this?
Upvotes: 0
Views: 345
Reputation: 1
You can try something like this:
public class Test {
public void accept(List<? extends Animal> animals) {
List<? super Animal> container = new ArrayList<>();
container.add(animals.get(0));
System.out.println(animals);
}
public void test() {
List<Animal> animals = new ArrayList<>();
accept(animals);
List<Dog> dogs = new ArrayList<>();
accept(dogs);
}
}
Upvotes: 0
Reputation: 109613
In List
is it specified: addAll(Collection<? extends E> c)
so it works:
animals.addAll(dogs);
The same for your method:
void foo(List<? extends Animal> animals) {
}
A supertype of the specified is not possible (foo(new Object()
) as parameter.
Upvotes: 0
Reputation: 489
List<? super Animal> animalList = new ArrayList<>();
animalList.add(new Animal());
animalList.add(new Dog("Snoopy"));
animalList.addAll(dogs);
so this list is mutable and can hold all Animals and its sub-classes like dog.
Be aware that List<Dog>
is not an instance of List<Animal>
.
for your second task method overloading might be nesseccary, depending on what you want to do with the list
Upvotes: 0