ArrayList包含同一个超类的不同对象 - 如何访问子类的方法 [英] ArrayList containing different objects of the same superclass - how to access method of a subclass

查看:183
本文介绍了ArrayList包含同一个超类的不同对象 - 如何访问子类的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨我想知道我的问题是否有一个简单的解决方案,

我有一个 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());

它们都实现了一个方法 move() - 当调用 move()时, Bird 过得很快。
我知道我可以使用这个来访问超类的常用方法和属性

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();
}

这没关系 - 但现在我想访问 move()方法子类 Bird 有。
我可以通过将 Animal 转换为 Bird

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();

在我的情况下,我不想这样做,因为这意味着我有3套不同的套装以上代码为 Animal 的每个子类型。

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?

推荐答案

从超类中确实没有很好的方法可以做到这一点,因为每个子类的行为都会有所不同。

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

为确保您实际调用相应的 move 方法,请更改 Animal 从超类到接口。然后,当您调用 move 方法时,您将能够确保为所需对象调用适当的移动方法。

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.

如果你想保留公共字段,那么你可以定义一个抽象类 AnimalBase ,并要求所有动物建立起来,但每个实现都需要实现 Animal 接口。

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.

示例:

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();
}

这篇关于ArrayList包含同一个超类的不同对象 - 如何访问子类的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆