不使用类型测试,声明 doTheTask?
我正在阅读 Cay Horstmann 编写的《Java For Every》。
当它说时我有点困惑:
不要使用类型测试
这是关于使用 instanceof
运算符进行特定类型测试,以实现随每个类而变化的行为,例如(直接取自书中):
if (q instanceof ChoiceQuestions) //Don't do this
{
//Do the task the ChoiceQuestion way
}
else if (q instanceof Question)
{
//Do the task Question way
}
显然这是一个糟糕的方法就好像您添加了一个像 NumericQuestion
这样的新类,您需要修改程序中进行类型测试的所有部分,添加另一个案例。
最好将类 NumericQuestion
添加到程序中。没有什么需要改变,因为我们使用的是多态性,而不是类型测试。 当您发现自己尝试在类层次结构中使用类型测试时,请重新考虑并使用多态性。在超类中声明一个方法doTheTask
,在子类中重写它并调用q.doTheTask()
我不明白的是最后一段,即上面的一段。有人能给我举个例子来说明这意味着什么吗? (我是一个视觉学习者)。在不使用类型测试的情况下,我们如何实际做到这一点?
I'm going through Java For Everyone by Cay Horstmann.
I'm a bit confused on when it says:
Don't Use Type Tests
This is about using instanceof
operator for specific type tests in order to implement behavior that varies with each class like (taken straight from the book):
if (q instanceof ChoiceQuestions) //Don't do this
{
//Do the task the ChoiceQuestion way
}
else if (q instanceof Question)
{
//Do the task Question way
}
Apparently this is a poor way to do it as if you have a new class like NumericQuestion
added you need to revise all parts of your program that make a type test, adding another case.
It is better to add class NumericQuestion
to the program. Nothing needs to change as we are using polymorphism, not type tests.
When ever you find yourself trying to use tyepe tests in a hierarchy of classes, reconsider and use polymorphism instead. Declare a method doTheTask
in the superclass, override it in the subclasses and call q.doTheTask()
What I don't understand is the last paragraph, the one above. Can someone shoe me an example of what it means please? (I'm kind of a visual learner). How do we actually do this without using tyep tests?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
重点是,而不是这样:
你应该这样做:
其中
Question
类包含:并且
ChoiceQuestion
类包含然后,当你得到一个新类
DrawQuestion 时
,它将包含,但调用
doTheTask()
的代码都不必更改! 没有风险,因为存在风险if (q 实例ChoiceQuestions)
模式,忘记添加新逻辑。而且(从长远来看,这实际上是更重要的部分)涉及特定类型问题的所有逻辑都集中在一个类中,而不是分散在应用程序的所有部分中。The point is that instead of this:
you should do this:
where the
Question
class contains:and the
ChoiceQuestion
class containsThen, when you get a new class
DrawQuestion
, it will containbut none of the code that calls
doTheTask()
will have to change! There is no risk, as there is with theif (q instanceof ChoiceQuestions)
pattern, of forgetting to add the new logic. And (this is actually the more important part in the long run) all the logic that concerns a specific kind ofQuestion
is concentrated in one class rather than spread out across all parts of the app.您应该理解的是,该类对其行为负责,而不是示例中的调用部分。我学到了“桌子应该自己画画”的原则:
可视化家具。你有一个油漆家具的油漆工类,但每次你声明一种家具时,你都必须“学习”它如何油漆一种新型家具。所以
Painter:
你所做的就是让所有家具都扩展一个“家具”类,该类知道
paintThySelf()
方法。所以现在画家只需要做,如果您添加一个 Chair 类,您将必须添加
paintThySelf()
方法,然后您就可以将其绘制出来。What you should understand is that the class is responsible for its behaviour, not the calling part from the exmaple. I learned this as "a table should paint itself" principle:
Visualise furniture. You have a painter class that paints furniture, but you have to "learn" it how to paint a new type of furniture everytime you declare one. So
Painter:
What you do is that you make all furniture extend a "furniture" class, that knows a method
paintThySelf()
. So now the painter just doesAnd if you add a Chair class, you will have to add the
paintThySelf()
method, and you can have it painted.作为设计原则,优先创建具有不同(覆盖)行为的子类,而不是使用
instanceof
来控制行为。As a design principle, favour creating a subclass that has different (overridden) behaviour over using
instanceof
to control behaviour.