instanceof 关键字用法
使用instanceof
关键字是否违背了面向对象编程
的本质? 我的意思是这是一个不好的编程习惯吗? 我在某处读到,使用 instanceof
关键字意味着设计可能不是那么好。有更好的解决方法吗?
Is using the instanceof
keyword against the essence of object oriented programming
?
I mean is it a bad programming practice?
I read somewhere that using instanceof
keyword means that the design may not be that good. Any better workaround?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一般来说是的。最好将所有依赖于特定类的代码保留在该类中,并且使用
instanceof
通常意味着您已将一些代码放在该类之外。看这个非常简单的例子:
理想情况下,我们希望所有特定于狗的行为都包含在 Dog 类中,而不是分散在我们的程序中。我们可以通过像这样重写我们的程序来改变这一点:
我们指定
Animal
必须有一个speak
方法。现在,SomeOtherClass
不需要知道每种动物的具体细节 - 它可以将其交给Animal
的子类。Generally speaking yes. It's best to keep all code that depends on being a specific class within that class, and using
instanceof
generally means that you've put some code outside that class.Look at this very simple example:
Ideally, we'd like all of the behaviour that's specific to dogs to be contained in the Dog class, rather than spread around our program. We can change that by rewriting our program like this:
We've specified that an
Animal
has to have aspeak
method. NowSomeOtherClass
doesn't need to know the particular details of each type of animal - it can hand that off to the subclass ofAnimal
.有很多推广虚拟方法的好答案,但
instanceof
也有其用途。想象一下,您迭代List
,以获取所有Urgent
对象。您可以使用 isUrgent() 来完成此操作,但我不确定它是否一定更简洁或更具可读性。此外,isUrgent()
需要让Event
知道其子类可能拥有相应的属性,这可能:Event
属于某个无法修改的库,则甚至不可能。There are many good answers promoting virtual methods, but
instanceof
has its uses as well. Imagine that you iterate overList<Event>
, to pick up allUrgent
objects. You might do it usingisUrgent()
but I am not sure if it were necessarily more concise or readable. Also,isUrgent()
would require makingEvent
aware that its subclasses may possess the respective property, which might:Event
belongs to some library that can not be modified.当通过虚拟方法可以达到相同的效果时(例如 thomson_matt 的示例),不鼓励使用
instanceof
。然而,在某些情况下有必要使用
instanceof
。例如,当您的代码从外部源(例如网络或返回Object
的第三方 API)获取对象时,您必须确定该对象的类型并采取适当的操作。Usage of
instanceof
is discouraged when same effect can be achieved via virtual methods, like in example of thomson_matt.However, it's necessary to use
instanceof
in some circumstances. For example, when your code gets Object from external source, say, network or third-party API which returnsObject
, and you must decide what is the type of this Object and act appropriately.支持向下转型和
instanceof
的多态性和动态绑定。这是“OO 方式”,使您能够编写不需要了解子类型的代码。示例
Favor polymorphism and dynamic binding to downcasting and
instanceof
. This is the "OO Way" and enables you to write code that doesn't need to know about subtypes.EXAMPLE
关键是不要将 instanceof 视为常见“正常实践”的一部分。就像一般的内省一样,instanceof 是一个特殊的工具,用于特定的非典型情况。每当您确实使用“instanceof”时,您可能还会发现自己使用平台的其他“特殊”部分,例如更普遍的反射。
只要当你发现自己在使用它时,你就承认你所做的只是一个拼凑的事情,而没有更优雅/实用的替代方案,那就没问题了。
也就是说,日常程序中最典型的情况可能是:
您可以尝试并坚持的一条经验法则是,不要求库的用户必须使用“instanceof”,而是在库内部有任何“instanceof”情况。
或者换句话说,您应该重新构建您的问题:“在什么情况下‘intsanceof’是解决方法?”
The key is to not see instanceof as being part of common "normal practice". Like introspection in general, instanceof is a special tool for use in particular, atypical circumstances. Whenever you do use 'instanceof', you may also find yourself using other 'special' parts of the platform such as reflection more generally.
So long as whenever you find yourself using it you accept that what you're doing is a kludge in the absence of a more elegant/practical alternative, then that's fine.
That said, the most typical circumstances in everyday programs are probably:
A rule of thumb you could try and stick to is to not require users of a library to have to use 'instanceof', but rather have any cases of 'instanceof' internal to the library.
Or put another way, you should re-frame your question: "What are the cases that 'intsanceof' is a workaround for?"
这是不鼓励的,因为人们可能会用它来做这样的事情:
相反,
Animal
应该有一个speak()
方法,其中Dog
和猫继承。在具有多态性和动态绑定的正确 OOP 中,您只需执行以下操作即可。
但是,在某些情况下,您必须使用
instanceof
来确定对象的特定类型。也许您家里有一份动物
清单,而您唯一想带出去walk()
的就是狗
。在这种情况下,您将迭代列表并仅walk()
狗。It's discouraged because people might use it to do something like this:
Instead,
Animal
should have aspeak()
method whichDog
andCat
inherit. In proper OOP with polymorphism and dynamic binding, you would then simply doHowever, there are some instances in which you must use
instanceof
to determine the specific type of an object. Perhaps you have a list ofAnimals
in your house and the only ones you want to take out for awalk()
are theDog
s. In that case you would iterate through your list and onlywalk()
the dogs.如果是创建工厂(见下文)呢?
在这种情况下,我认为 Animal 子类知道如何为自己构建笼子是不合适的。它似乎超出了 Animal 的范围,并迫使 Animal 子类采取非 Animal 固有的行为。
How about in the case of a creation factory (See below)?
In this case, I don't think it is appropriate for an Animal subclass to know how to build a cage for itself. It seems out of out of scope of what an Animal is and forces the Animal subclass to take on behaviors that are not intrinsic to what an Animal is.
instaceOf 操作的另一个用途是错误处理。如果您对异常有类似的错误处理,并且您希望将所有内容集中在一个地方,您可以使用:
使用上面的代码,您可以避免使用许多
块,而只使用一个块
另外,还有一件事是,您是否检查 java 源代码代码,你会发现 instaceof 的很多用法..
还有一个很好的链接:
有关 instaceof 用法的文章
Another usage of instaceOf operation could be error handling. If you have similar error handling for exceptions, and you want to have it all in one place you can use:
with above code, you avoid to have many
blocks and instead have just one
Also, one more thing is, is you check java source code, you will find so many usages of instaceof..
And one good link:
article about usage of instaceof