说我有3个这样的课程:
class A {}
class B extends A {}
class C extends A {}
是否可以确定某个特定对象是A
,B
还是C
的实例?
我认为这样的事情可能有用:
if (myObject.getClass().isInstance(B.class)) {
// do something for B
} else (myObject.getClass().isInstance(C.class)) {
// do something for C
} else {
// do something for A
}
但是在阅读了一点之后我认为它总是会评估为B,因为它只是测试一个演员是否有效并且它们之间没有实质性差异。
答案 0 :(得分:9)
更简单,更快速的代码是:
if (myObject instanceof B) {
} else if (myObject instanceof C) {
} else if (myObject instanceof A) {
}
请注意,订单很重要:您必须最后对A
进行测试,因为B
和C
的实例也会成功。
但是,您的原始代码几乎可以正常工作。 Class.isInstance
检查值是否真的是给定类或任何超类的实例。因此,如果myObject
是C
的实例,那么B.class.isInstance(myObject)
将返回false。你所犯的错误就是你在getClass()
上不必要地拨打myObject
,而不是使用B.class
等。
如果您在编译时不知道自己感兴趣的类,那么这就是您要采用的方法 - instanceof
运算符仅在您可以在代码中静态指定类型时才有效。
现在,如果你想知道myObject
是的实例 B
(而不是子类),那么只需使用:
if (myObject.getClass() == B.class)
(当然,如果myObject
是空引用,这将会爆炸。)
答案 1 :(得分:7)
这样做:
if (myObject instanceof B) {
// do something for B
} else (myObject instanceof C) {
// do something for C
} else {
// do something for A
}
答案 2 :(得分:1)
您还可能希望查看double dispatch idiom,它是根据不支持多方法的语言中的参数类型更改行为的OO方式。
答案 3 :(得分:0)
有instanceof
运算符执行您想要的操作,正如其他人已经回答的那样。
但要注意,如果你需要这样的东西,这表明你的程序设计可能存在缺陷。更好,更面向对象的方法是使用多态:将方法放在超类A中,在B和C中覆盖该方法,并在myObject上调用方法(应该有类型A):
A myObject = ...; // wherever you get this from
// Override someMethod in class B and C to do the things that are
// specific to those classes
myObject.someMethod();
instanceof
是丑陋的,应该尽可能地避免,就像铸造丑陋,可能不安全一样,应该避免。
答案 4 :(得分:0)
你可以这样做
if (myObject.getClass() == B.class) {
// do something for B (not subclasses of b!!!)
} else if(myObject.getClass() == C.class) {
// do something for C (not subclasses of c!!!)
} else if(myobject.getClass() == A.class) {
// do something for A (not subclasses of A!!)
} else if(myobjects instanceof A){
//all other subclasses of A
}