2

我正在做一个简单的 Zoo 应用程序来理解 Java 中的面向对象概念。

我的模型如下: 1)动物园有许多笼子 2)笼子有猫科动物、灵长类动物或鸟类的混合物 3)动物可以吃、睡或喝 4)猫科动物延伸动物(做额外的猫科动物的事情)5 )灵长类动物扩展动物(做额外的灵长类动物的东西)6)鸟扩展动物(做额外的鸟东西)

问题:

虽然在动物园中处理 x 数量的笼子(笼子的数组列表)非常容易,但我正在努力处理笼子里的动物。我发现我需要一个对象的 ArrayList。

到目前为止一切顺利,但是当我试图找回我的动物并让他抓一个柱子时,它不再是猫科动物,而是一个对象。

public class Cage{

        private String name;
        private ArrayList<Object> animals = new ArrayList<Object>();

        public Cage(String name){
            this.name = name;
        }

        public void addFeline(String name){
            Feline newFeline= new Feline(name);
            this.animals.add(newFeline);
        }

        public void addPrimate(String name){
            Primate newPrimate= new Primate(name);
            this.animals.add(newPrimate);
        }

        public void addBird(String name){
            Bird newBird= new Bird(name);
            this.animals.add(newBird);
        }

        public void removeAnimal(int index){
            this.animals.remove(index);
        }

        public Object getAnimal(int index){
            Object myAnimal = this.animals.get(index);
            return myAnimal;
        }
    }

我称之为:

Zoo myZoo = new Zoo("My Zoo");
myZoo.addCage("Monkey Exhibit");
Cage myCage = myZoo.getCage(0);
myCage.addFeline("Leo");
Object MyAnimal = myCage.getAnimal(0);

问题:如何将 Object 转回 Feline 类的实例,以便它可以 Scratch a Post?

4

4 回答 4

3

我认为解决这个问题的最好方法是使用策略设计模式。

Feline、Primate 和 Bird 应该实现接口 Animal。然后笼子会有一个方法 public void addAnimal(Animal animal);

猫科动物、灵长类动物和鸟类的对象创建应该在 Cage 之外。

如果这有帮助,我已经整理了一些代码。我会设计类似于下面的应用程序。

行为应该使用接口封装。例如饮食行为

public interface Animal {
    public String getName();
}
public interface EatingBehaviour {
    public void howManyTimes();
}

public class RealLionEatingBehaviour implements EatingBehaviour{
    @Override
    public void howManyTimes() {
        System.out.println("I eat once a day");
    }
}

public class ToyLionEatingBehaviour implements EatingBehaviour {
    @Override
    public void howManyTimes() {
        System.out.println("I never eat! I am a toy lion.");
    }
}

public abstract class Feline implements Animal{
    public abstract void scratchPost();
    private EatingBehaviour eatingBehaviour;
    public EatingBehaviour getEatingBehaviour() {
        return eatingBehaviour;
    }
    public void setEatingBehaviour(EatingBehaviour eatingBehaviour) {
        this.eatingBehaviour = eatingBehaviour;
    }
}

public class Lion extends Feline {
    private String name;
    public String getName() {
        return this.name; 
    }
    public void setName(String name) {
        this.name = name; 
    }
    Lion (String name) {
        this.name=name;
    }
    public void scratchPost(){
        System.out.println(getName() + " Lion Scratching Post!");
    }   
}

public class AnimalFactory {
    public static Animal getAnimalInstance(String type, String name){
        Animal animal=null;
        if ("lion".equalsIgnoreCase(type)) {
            animal = new Lion(name);
        }
        return animal;
    }
}

import java.util.ArrayList;
import java.util.List;

public class Cage {
    private List<Animal> animals = new ArrayList<Animal>();
    public void addAnimal(Animal animal) {
        animals.add(animal);
    }
    public void removeAnimal(int index){
        this.animals.remove(index);
    }
    public Animal getAnimal(int index){
        return this.animals.get(index);
    }   
}

public class Zoo {
    public static void main(String args[]) {
        Cage cage = new Cage();
        Animal animal = null;
        animal = AnimalFactory.getAnimalInstance("Lion", "Sweety");
        cage.addAnimal(animal);
        Animal animalFromCage = cage.getAnimal(0);
        if (animalFromCage instanceof Feline) {
            Feline feline = (Feline) animalFromCage;
            feline.setEatingBehaviour(new RealLionEatingBehaviour());
            feline.scratchPost();
            feline.getEatingBehaviour().howManyTimes();
            feline.setEatingBehaviour(new ToyLionEatingBehaviour());
            feline.getEatingBehaviour().howManyTimes();
        }
    }
} 
于 2013-08-04T23:40:45.470 回答
2

使用演员表:

Object myAnimal = myCage.getAnimal(0);
Feline f = (Feline) myAnimal;
于 2013-08-04T23:25:30.963 回答
0
private List<Animal> animals = new ArrayList<Animal>();
    public void findAnimal(int index) {
        Animal myAnimal = animals.get(index);
        if (myAnimal instanceof Feline) {
            Feline feline = (Feline) myAnimal;
            //do the work with Feline
        } else if (myAnimal instanceof Primate) {
            //do the work with Primate
        }
        // continue with the other types.
    }

这将避免意外的类转换异常。由于您知道类型,因此在 Arraylist 中使用超类型(动物)而不是对象。如果是对象,您可以将任何内容添加到列表中。

于 2013-08-04T23:47:36.497 回答
-1

您应该使用 anArrayList<? extends Animal>而不是ArrayList<Object>. 然后,您会将返回值强制转换为Animal.

于 2013-08-04T23:26:34.960 回答