可接受的实例使用

2022-09-04 02:36:26

我是Java的新手,正在努力解决设计问题。我知道使用可能表示设计缺陷,我理解经常给出的类作为示例,替换和与等。instanceofAnimal/Dog/Catbark()meow()makenoise()

我的问题是,如果我需要根据子类的类型调用没有相应方法的方法,那么什么是明智的设计?例如,如果我想在类是 a 时调用新方法,但如果它是一个 ,则不执行任何操作,该怎么办?biteleash()DogCat

我确实考虑过让其中什么都不做,并在 中覆盖它,但是有很多像这样的方法,所以这似乎是一个笨拙的解决方案。类似地,如果调用方需要根据它持有的子类做一些不同的事情,该怎么办?如果子类是 ?这里是可以接受的,还是有更好的方法?biteleash()AnimalDogCatinstanceof

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

答案 1

作文在这里会帮助你,在Java中是习语。

设计一个名为 的接口,例如。这由 实现,但不是 .LeashableDogCat

您可以尝试强制转换引用,而不是使用 ,以查看它是否由您的特定对象实现。instanceofLeashable

在我看来,你应该继续类似的方式:也构建一个界面。也许甚至只是因为为什么嘈杂只与动物有关?例如,对于 a 实现该功能将具有超出 或 的技术挑战。良好的可维护程序可以隔离复杂性区域,而组合可以帮助您实现这一目标。NoisyAnimalNoisyParrotCatDog


答案 2

不应使用具体类。实例本身不是问题。它的存在是有原因的。您应该使用接口进行松散耦合,即您的代码不应依赖于具体的类实现。我建议你尽可能使用接口(即IAnimal而不是Animal)

而不是检查狗,你应该使用像ILeashable这样的界面(是的,对于一个名字来说有点荒谬),然后:

public interface ILeashable {
   //add other methods which is connected to being on a leash
   void biteLeash();
}

class Dog implements ILeashable {...}

此外,没有一种方法可以做到这一点,有某些模式,即装饰器或依赖倒置,在这种情况下可能会对您有所帮助。