我的课程中有以下课程:
public abstract class Question {
private Topic topic;
private String text;
// methods
}
public class OpenQuestion extends Question {
// methods
}
public class MultipleChoiceQuestion extends Question {
private List<String> options = new ArrayList<String>();
private String correct;
// methods
}
此外,我还有另一个课程测试:
Question question;
// if the question is open
if(question instanceof OpenQuestion) {
...
}
// if the question is multiple choice
if(question instanceof MultipleChoiceQuestion) {
...
}
我正试图寻找instanceof
的替代方案,因为我被告知它违反了OOP原则。
还有其他更好的方法可以知道问题是开放还是多项选择?
答案 0 :(得分:4)
instanceof
关键字本身不会破坏OOP原则。它们可能意味着你应该使用多态来执行逻辑。
而不是:
if(question instanceof OpenQuestion) {
...
}
//Countless ifs
if(question instanceof MultipleChoiceQuestion) {
...
}
你应该
question.doAction();
另一个例子(更明确):
abstract class Animal{
public abstract void speak();
}
class Dog extends Animal{
public void speak(){ System.out.println("Bark!"); }
}
class Cat extends Animal{
public void speak(){ System.out.println("Meow!"); }
}
答案 1 :(得分:0)
当然你可以看到这个例子:
import java.lang.reflect.*;
import java.awt.*;
class SampleName {
public static void main(String[] args) {
Button b = new Button();
printName(b);
}
static void printName(Object o) {
Class c = o.getClass();
String s = c.getName();
System.out.println(s);
}
}
答案 2 :(得分:0)
如果您对OO设计感兴趣,那么请考虑是否可以执行以下操作:让Question类调用一个方法,而不是if语句中的代码
public abstract class Question {
private Topic topic;
private String text;
// methods
public void abstract doSomething(Object arg);
}
public class OpenQuestion extends Question {
@Override
public void doSomething(Object arg) {
// do something with an open question
}
// other methods
}
public class MultipleChoiceQuestion extends Question {
private List<String> options = new ArrayList<String>();
private String correct;
@Override
public void doSomething(Object arg) {
// do something with an open question
}
// other methods
}
另一个类中的代码是:
Question question;
question.doSomething(arg);
为了传递Question对象不知道的任何信息,可以使用参数中的参数,但是当你想要做某事时,你可以使用它。
答案 3 :(得分:0)
它本身不是破坏OOP的实例,它知道你的类是什么特定类是一个打破它的实例。
如果你的班级是“动物”,可以是狗,猫或鸟... Animal.legs()应该足以在不知道动物类型的情况下计算腿部 - 当然这很容易。更难的情况是某些动物的方法对其他动物没有意义。
以不适用于狗或猫的案例fly()为例。在这种情况下,有一些解决方案,奇怪的是在这种情况下,instanceof可能是最好的!
您可以: 仅在鸟上实现fly()并反映鸟是否有fly()方法。 在每个类上实现canFly()和fly(),如果不能,则fly()抛出异常。
这些都不是好的 - 根本不是OO,无缘无故是丑陋和重复的(如果你有可用的鸭子,第一个也不错,但即便如此也不是最明显的解决方案)
那么什么是好的解决方案?有一个“Flies”接口声明了一个fly()方法,只有“Bird”实现了Flies。在这种情况下,instanceof是一个非常好的解决方案 - 可能是最好的!
坏: 如果(动物实体鸟) ((鸟)动物).fly()
好: 如果(动物实例苍蝇) ((蝇)动物).fly()
这是一个非常微妙的区别,直到你明白为什么 - 当你添加蝙蝠时会发生什么?在第一个你有:
if(animal instancef Bird)
((Bird)animal).fly()
else if(animal instancef Bat)
((Bat)animal).fly()
这是一个开关,构造,每当你发现自己用OO语言编写一个switch结构时,你可能做错了(这就是他们说instanceof错误的原因,因为它导致了switch结构)
只要Bat实现Flies,第二个示例仍然可以保持不变,并且将继续执行您实现的任何新对象。这太棒了。
使用接口这种方式比鸭子打字和反射更有优势 - 因为它具体而且经过深思熟虑。你不会不小心在Pants对象上调用.fly()并找回你没想到的Zipper,你可以检查“bat”的代码并轻松理解意图。