【问题标题】:Does Java have an "is kind of class" test methodJava 是否有“是一种类”的测试方法
【发布时间】:2010-10-30 00:51:56
【问题描述】:

我有一个基类Statement,其他几个类继承自它,命名为IfStatementWhereStatement 等...在if 语句中执行测试以确定哪个类的最佳方法是什么?实例派生自 Statement 类?

【问题讨论】:

    标签: java reflection inheritance evaluation


    【解决方案1】:
    if(object instanceof WhereStatement) {
       WhereStatement where = (WhereStatement) object;
       doSomething(where);
    }
    

    请注意,这样的代码通常意味着您的基类缺少多态方法。即doSomething() 应该是Statement 的方法,可能是抽象的,被子类覆盖。

    【讨论】:

    • 感谢您提供更多信息!我会研究一下,看看是否有一种干净的方法来改进设计。
    • +1 作为答案,但我要补充一点,instanceof 有很多有效的用途——它并不总是一种设计气味。例如,如果 doSomething() 只适用于 where 子句,那么这种模式可能比人为地使 doSomething() 成为 Statement 类的一部分(它在逻辑上不适合)更好。
    • 另一个instanceof 有用的例子。在 JavaFX 中,您有一个窗格。我需要遍历子节点树。 getChildren() 返回节点。但如果其中一个节点是窗格,我也需要遍历 its 子节点。 Node 没有getChildren() 方法,也不是我可以添加的。所以我必须使用node instanceof Pane 来查看是否需要将Node 强制转换为Pane 并遍历它的子节点。
    【解决方案2】:
    if (obj.getClass().isInstance(Statement.class)) {
       doStuffWithStatements((Statement) obj));
    }
    

    这种技术的好处(与“instanceof”关键字相反)是您可以将测试类作为对象传递。但是,是的,除此之外,它与“instanceof”相同。

    注意:我故意避免对类型实例检查是否是正确的事情进行社论。是的,在大多数情况下,最好使用多态性。但这不是 OP 所要求的,我只是在回答他的问题。

    【讨论】:

    • 为什么不使用更简单的 instanceof 检查?
    • instanceof 不像 goto 那样邪恶。它被添加到语言中以及为什么它没有被弃用是有原因的。
    • +1 表示没有“编辑类型实例检查是否是正确的做法”
    【解决方案3】:

    你的问题的答案是 instanceof。

    但是,请记住,如果您的代码需要 instanceof,则表明您的设计有问题。在某些情况下 instanceof 是合理的,但它们是例外。通常,如果您的子类需要表现不同,则必须使用多态性而不是 if()s。

    【讨论】:

    • 对你的推荐我唯一要补充的是对接口编程的强烈建议。
    【解决方案4】:

    课堂上的isAssignableFrom(java.lang.Class)是你的答案。

    【讨论】:

      【解决方案5】:

      试试这个:

      if (Statement.class.isInstance(obj)) {
          doStuffWithStatements((Statement) obj));
      }
      

      因为Class.isInstance() 方法将对象实例作为参数。

      【讨论】:

        【解决方案6】:

        不是以面向对象的方式做事的方式,它是对旧代码/数据二分法的回归。现在这不一定是一件坏事(如果你知道自己在做什么),但它应该留给像 C 这样的非面向对象的语言。

        如果设计得当,您就不需要这种行为。而不是构造:

        if (obj.getClass().isInstance(Statement.class)) {
            doStuffWithStatements((Statement) obj));
        }
        

        (为“窃取”他的代码向 benjismith 道歉),您确实应该让对象本身对其自己的活动负责:

        obj.doStuff();
        

        然后每个不同的obj 类将有自己的doStuff 定义。这是正确的做法。

        【讨论】:

        • 如果只有一个子类可以做事(™paxdiabio)并且你有一个对象数组,其中一些是子类的超类,那么这是更好的方法(而不是而不是向超类添加无操作的 doStuff 方法,这可能没有意义(或“只是错误”))。
        • @geowar,如果你有一个非同质的东西的集合,它们可能不应该在集合中。或者,至少,您不应该以想要 doStuff 的方式迭代该集合。有多种方法可以处理此问题,但在进行更改时将其绑定到类名或类型可能会出现很大问题。在继承/OO 的世界中,为超类设置一个不希望对此情况执行任何操作的 null 函数实际上是一个非常有效的解决方案,从而使处理代码更加简洁。
        猜你喜欢
        • 2013-03-18
        • 2021-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 2016-01-19
        • 1970-01-01
        相关资源
        最近更新 更多