Lets say I know for certain that a list contains only elements of type B which extends A. Here is an example representing my situation:
public static class Animal {
public void feed() {}
}
public static class Cat extends Animal {
}
public static class Zoo {
public List<Animal> m_animals;
public Zoo() {
m_animals = new ArrayList<Animal>();
}
public void feedAnimals() {
for(Animal animal : m_animals)
animal.feed();
}
}
public static class CatZoo extends Zoo {
public void addCat(Cat cat) {
m_animals.add(cat);
}
List<Cat> getCats() {
List<Cat> cats = new ArrayList<Cat>();
for(Animal cat : m_animals)
cats.add((Cat) cat);
return cats;
}
}
I feel like I'm doing something wrong but I can't quite put my finger on it. CatZoo
is still a Zoo
and I need the Zoo
methods. Cat
is definitely an Animal
and I need the Animal
methods. Anybody who deals with CatZoo
should only deal with Cat
and not Animal
. But getCats()
becomes super inefficient. Is there a better way to do this?
I think what you're looking for is a generic Zoo
. That way you can move common logic to the base class while letting the subclasses know what type they're working with:
public static class Zoo<A extends Animal> {
public List<A> m_animals;
public void add(A animal) {
m_animals.add(animal);
}
}
public static class CatZoo extends Zoo<Cat> {
public void meow() {
for (Cat cat : m_animals)
cat.meow();
}
}