I've been trying to play with generics and polymorphism. I've come across a problem I can't get my head around.
Say I have
public abstract class Animal {
private age;
private weight;
public Animal(){}
public void Move(){
//stuff
}
public void Eat(){
//stuff
}
//Getters and setters
}
And then
public Cat extends Animal {
//Constructors
}
public Snake extends Animal {
//Constructors
public void ShedSkin(){
//stuff
}
}
I also have my own class "MyAbstractClass". It's here I can't seem to work things out.
public abstract class MyAbstractClass {
private List<Animal> myAnimalList;
public MyAbstractClass(){}
public MyAbstractClass(List<? extends Animal> animalList) {
this.myAnimalList = animalList;
}
public List<Animal> getAnimalList() {
return myAnimalList;
}
//Stuff which DOES NOT add to the list
}
I want to be able to do:
public class MyCatClass extends MyAbstractClass {
public MyCatClass(List<Cat> catList) {
super(catList);
}
}
public class MySnakeClass extends MyAbstractClass {
public MySnakeClass(List<Snake> snakeList) {
super(snakeList);
}
public ShedSkin(){
(Snake)getAnimalList().get(0).ShedSkin(); //Dont worry about indexing
}
}
Then
public static void main(string[] args) {
//Make list of cats
//Make list of snakes
MyCatClass cats = new MyCatClass(catList);
MySnakeClass snakes = new MySnakeClass(snakeList);
snakes.ShedSkin();
}
This does not work for me. It fails to compile at public MyAbstractClass(List<? extends Animal> animalList). This is a bit over my java experience and would greatly appreciated some guidance. I hope the example classes are made clear enough to understand my intention.
Compiler tells me: java.util.List<Animal> in MyAbstractClass cannot be applied to java.util.List<capture<? extends Animal>>
Thanks.
Edit: Looks like I'll have to spell out what I'm trying to do. I have a list of animals which may or may not have more fields and methods than the superclass, but they all extend the superclass. I also want a class which takes in a list of a single type of animal, and call methods on or over each element in the List. I won't be adding anything to the list so that shouldn't be a problem. The reason I'm splitting up like this is because between all the Animals, there is alot of similarity, but some animals have specialties. The class taking in the List needs to be able to handle these particularities. Hence have the worker class extend a superclass and implement extra methods.
EDIT2: Worked it out!
public abstract class MyAbstractClass {
private List<? extends Animal> myAnimalList;
public MyAbstractClass(){}
public MyAbstractClass(List<? extends Animal> animalList) {
this.myAnimalList = animalList;
}
public List<Animal> getAnimalList() {
return myAnimalList;
}
//Stuff which DOES NOT add to the list
}
Both the field and the constructor need to be List<? extends Animal> foobar.
Constructive brainstorming session!
EDIT3: Dima's method is better.
List<? extends Animal>andList<Animal>are different things. The first can be aList<Cat>, in which you cannot add aDog, for example. The second is a list into which anyAnimal, cats or dogs, can be added. Mass hysteria! Apropos tutorial topic.