-1

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?

A.Hristov
  • 481
  • 1
  • 4
  • 13

1 Answers1

2

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();
    }
}
shmosel
  • 49,289
  • 6
  • 73
  • 138