【发布时间】:2010-10-30 00:51:56
【问题描述】:
我有一个基类Statement,其他几个类继承自它,命名为IfStatement、WhereStatement 等...在if 语句中执行测试以确定哪个类的最佳方法是什么?实例派生自 Statement 类?
【问题讨论】:
标签: java reflection inheritance evaluation
我有一个基类Statement,其他几个类继承自它,命名为IfStatement、WhereStatement 等...在if 语句中执行测试以确定哪个类的最佳方法是什么?实例派生自 Statement 类?
【问题讨论】:
标签: java reflection inheritance evaluation
if(object instanceof WhereStatement) {
WhereStatement where = (WhereStatement) object;
doSomething(where);
}
请注意,这样的代码通常意味着您的基类缺少多态方法。即doSomething() 应该是Statement 的方法,可能是抽象的,被子类覆盖。
【讨论】:
instanceof 有很多有效的用途——它并不总是一种设计气味。例如,如果 doSomething() 只适用于 where 子句,那么这种模式可能比人为地使 doSomething() 成为 Statement 类的一部分(它在逻辑上不适合)更好。
instanceof 有用的例子。在 JavaFX 中,您有一个窗格。我需要遍历子节点树。 getChildren() 返回节点。但如果其中一个节点是窗格,我也需要遍历 its 子节点。 Node 没有getChildren() 方法,也不是我可以添加的。所以我必须使用node instanceof Pane 来查看是否需要将Node 强制转换为Pane 并遍历它的子节点。
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
这种技术的好处(与“instanceof”关键字相反)是您可以将测试类作为对象传递。但是,是的,除此之外,它与“instanceof”相同。
注意:我故意避免对类型实例检查是否是正确的事情进行社论。是的,在大多数情况下,最好使用多态性。但这不是 OP 所要求的,我只是在回答他的问题。
【讨论】:
你的问题的答案是 instanceof。
但是,请记住,如果您的代码需要 instanceof,则表明您的设计有问题。在某些情况下 instanceof 是合理的,但它们是例外。通常,如果您的子类需要表现不同,则必须使用多态性而不是 if()s。
【讨论】:
课堂上的isAssignableFrom(java.lang.Class)是你的答案。
【讨论】:
试试这个:
if (Statement.class.isInstance(obj)) {
doStuffWithStatements((Statement) obj));
}
因为Class.isInstance() 方法将对象实例作为参数。
【讨论】:
这不是以面向对象的方式做事的方式,它是对旧代码/数据二分法的回归。现在这不一定是一件坏事(如果你知道自己在做什么),但它应该留给像 C 这样的非面向对象的语言。
如果设计得当,您就不需要这种行为。而不是构造:
if (obj.getClass().isInstance(Statement.class)) {
doStuffWithStatements((Statement) obj));
}
(为“窃取”他的代码向 benjismith 道歉),您确实应该让对象本身对其自己的活动负责:
obj.doStuff();
然后每个不同的obj 类将有自己的doStuff 定义。这是正确的做法。
【讨论】: