Java - 使用超类对象数组避免强制转换

时间:2012-05-23 18:21:14

标签: java arrays casting clone subclass

我有很多子类实现了超类Animal(狗,猫,老鼠等)

所以我这样做:

Animal[] arrayOfAnimals = new Animal[100];

我把狗,猫等物品放进去。

当我从中得到一些东西时,我

If(arrayOfAnimals[1] instanceof Dog) {
    ((Dog)(arrayOfAnimals[1])).speak();
}

else if(arrayOfAnimals[1] instanceof Cat) {
    ((Cat)(arrayOfAnimals[1])).speak();
}

因为我需要知道动物是猫还是狗,因为例如,每个人都说不同。

现在假设我有许多动物的子类,我会连续得到许多“如果......”

我的问题是:有没有办法避免这种情况?我已经尝试过使用接口(Animal - >接口,Dog,Cat等实现动物),但是在我的项目中,数组必须是可克隆的,如果Animal是,则无法克隆数组“Animal [] arrayOfAnimals”一个接口(该数组中的对象不会被克隆)

2 个答案:

答案 0 :(得分:9)

  

因为我需要知道动物是猫还是狗,因为例如每个动物都说不同。

这听起来像是实现细节 - 如果每个动物都能以某种形式说话,你应该将speak()方法作为抽象方法放入Animal。然后,每个子类将覆盖它以提供实现。然后你可以使用

arrayOfAnimals[1].speak();

...而且多态将负责使用正确的实现。

可以克隆一个接口类型的数组,btw:

interface Foo {
}

class FooImpl implements Foo {
}

public class Test {
    public static void main(String[] args) {
        Foo[] foos = { new FooImpl() };

        Foo[] clone = (Foo[]) foos.clone();
        System.out.println(foos[0] == clone[0]); // true
    }
}

请注意,无论涉及何种类型,在数组上调用clone()都不会克隆每个元素 - 新数组将包含与旧数组相同的引用。这是一个浅薄的副本。如果你想这样做,你必须自己编写代码(或找到第三方库)。

答案 1 :(得分:1)

为什么不将speak()移动到超类并让子类覆盖它?