This question already has answers here:
Is this an acceptable use of instanceof?

(2个答案)


5年前关闭。




我是Java的新手,正在为设计问题而苦苦挣扎。我知道instanceof的使用可能表明存在设计缺陷,并且我了解经常使用的Animal/Dog/Cat类作为示例,将bark()meow()替换为makenoise()等。

我的问题是,如果我需要根据子类的类型调用没有相应方法的方法,那是什么明智的设计呢?例如,如果我想调用一个新的方法biteleash()(如果该类是Dog),但如果它是Cat,则什么也不做呢?

我确实考虑过在biteleash()中添加Animal而不执行任何操作,并在Dog中覆盖它,但是有很多类似这样的方法,因此这似乎很笨拙。同样,如果调用方需要根据其拥有的子类进行不同的操作,该怎么办?如果子类是Cat,终止吗? instanceof在这里可以接受吗,还是有更好的方法?
public class Animal {

    String name;

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

    public String getName() {
        return name;
    }

    public void makeNoise() {
        System.out.println("Some noise for a generic animal!");
    }

}

public class Cat extends Animal {

    public Cat(String name) {
        super(name);
    }

    @Override
    public void makeNoise() {
        System.out.println("Meow");
    }
}

public class Dog extends Animal {

    public Dog(String name) {
        super(name);
    }

    @Override
    public void makeNoise() {
        System.out.println("Woof");
    }

    public void biteLeash() {
        System.out.println("Leash snapped!");
    }
}

import java.util.Random;

public class CodeExample {


    public static void main(String[] args) {

        Animal animal = getSomeAnimal();
        System.out.println("My pet is called " + animal.getName());
        animal.makeNoise();

        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.biteLeash();
            // do lots of other things because animal is a dog
            // eg. sign up for puppy training lessons
        }
    }

    private static Animal getSomeAnimal() {
        Animal animal;
        Random randomGenerator = new Random();
        int randomInt = randomGenerator.nextInt(100);
        if (randomInt < 50) {
            animal = new Dog("Rover");
        }
        else {
            animal = new Cat("Tiddles");
        }
        return animal;
    }
}

最佳答案

组合将在这里为您提供帮助,并且在Java中是惯用的。

设计一个名为Leashable的接口(interface)。这是通过Dog实现的,而不是Cat实现的。

您可以尝试对instanceof进行引用强制转换,以查看其是否由您的特定对象实现,而不是使用Leashable

我认为,您应该以类似的方式继续:也构建一个NoisyAnimal接口(interface)。也许甚至是Noisy,因为为什么嘈杂只与动物有关?例如,为Parrot实现该功能将面临CatDog之外的技术难题。良好的可维护程序可以隔离复杂性区域,并可以帮助您实现这一目标。

09-26 08:40