Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ArrayList containing different objects of the same superclass - how to access method of a subclass

Hi I'm wondering if there is a simple solution to my problem,

I have an ArrayList:

ArrayList <Animal> animalList = new ArrayList<Animal>(); 

/* I add some objects from subclasses of Animal */

animalList.add(new Reptile());
animalList.add(new Bird());
animalList.add(new Amphibian());

They all implement a method move() - The Bird flies when move() is called. I know I can access common methods and properties of the super class by using this

public void feed(Integer animalIndex) {
    Animal aAnimal = (Animal) this.animalList.get(animalIndex);
    aAnimal.eat();
}

That's fine - but now I would like to access the move() method the subclass Bird has. I could do this by casting the Animal as a Bird:

Bird aBird = (Bird) this.animalList.get(animalIndex);
aBird.move();

In my situation I don't want to do this, as it will mean I have 3 different sets of the above code one for each subtype of Animal.

It seems a bit redundant, is there a better way?

like image 350
whiteElephant Avatar asked Apr 14 '13 03:04

whiteElephant


People also ask

Can ArrayList store subclass objects?

As far as it's concerned, the ArrayList only holds references to SuperClass -type objects, and it can only call SuperClass 's methods on objects it retrieves from it.

Does a subclass inherit methods from superclass?

A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.

Can a superclass access a subclass variable Java?

Classes in Java exist in a hierarchy. A class in Java can be declared as a subclass of another class using the extends keyword. A subclass inherits variables and methods from its superclass and can use them as if they were declared within the subclass itself: class Animal { float weight ; ...

What is the super class of ArrayList in Java?

When we examine the API (Application Programming Interface) of Java's ArrayList, we notice that ArrayList has the superclass AbstractList . AbstractList , in turn, has the class Object as its superclass. Each class can directly extend only one class.


1 Answers

There really isn't a nice way to do this from the superclass, since the behavior of each subclass will be different.

To ensure that you're actually calling the appropriate move method, change Animal from a superclass to an interface. Then when you call the move method, you'll be able to ensure that you're calling the appropriate move method for the object you want.

If you're looking to preserve common fields, then you can define an abstract class AnimalBase, and require all animals to build off of that, but each implementation will need to implement the Animal interface.

Example:

public abstract class AnimalBase {
    private String name;
    private int age;
    private boolean gender;

    // getters and setters for the above are good to have here
}

public interface Animal {
    public void move();
    public void eat();
    public void sleep();
}

// The below won't compile because the contract for the interface changed.
// You'll have to implement eat and sleep for each object.

public class Reptiles extends AnimalBase implements Animal {
    public void move() {
        System.out.println("Slither!");
    }
}

public class Birds extends AnimalBase implements Animal {
    public void move() {
        System.out.println("Flap flap!");
    }
}

public class Amphibians extends AnimalBase implements Animal {
    public void move() {
        System.out.println("Some sort of moving sound...");
    }
}

// in some method, you'll be calling the below

List<Animal> animalList = new ArrayList<>();

animalList.add(new Reptiles());
animalList.add(new Amphibians());
animalList.add(new Birds());

// call your method without fear of it being generic

for(Animal a : animalList) {
    a.move();
}
like image 100
Makoto Avatar answered Sep 18 '22 02:09

Makoto