我是Java的新手并且在设计问题上苦苦挣扎.我知道使用instanceof可能表示设计缺陷,我理解经常给出的Animal/Dog/Cat类作为例子,替换bark()和meow()使用makenoise()等.
我的问题是,如果我需要根据子类的类型调用没有相应方法的方法,那么什么是合理的设计?例如,如果我想调用一个新方法,biteleash()如果该类是a,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;
}
}
Run Code Online (Sandbox Code Playgroud)
Bat*_*eba 10
组合将在这里帮助您,并且在Java中是惯用的.
设计一个名为的界面,比如说Leashable.这是由a实现的Dog,但不是a Cat.
instanceof您可以尝试使用引用Leashable来查看它是否由您的特定对象实现,而不是使用.
在我看来,你应该继续以类似的方式:建立一个NoisyAnimal界面.也许就像Noisy为什么噪音只与动物有关?Parrot比如说,实现这一目标将会产生超出Cat或的技术挑战Dog.良好的可维护程序隔离了复杂性和组合区域,可帮助您实现这一目标
你不应该使用具体的类.实例本身不是问题.它存在是有原因的.您应该使用松散耦合的接口,即您的代码不应该依赖于具体的类实现.我建议你尽可能使用接口(即IAnimal而不是Animal)
你应该使用像ILeashable这样的界面(对于名字来说有点荒谬),而不是检查Dog,然后:
public interface ILeashable {
//add other methods which is connected to being on a leash
void biteLeash();
}
class Dog implements ILeashable {...}
Run Code Online (Sandbox Code Playgroud)
也没有一种方法可以做到这一点,有一些模式,即装饰器或依赖倒置,在这种情况下可能会帮助你.
| 归档时间: |
|
| 查看次数: |
1293 次 |
| 最近记录: |