如果父实例的实例,实例是否返回 true?

我有一个扩展的类。ChildParent

Parent child = new Child();

if (child instanceof Parent){
    // Do something
}

这是返回 true 还是 false,为什么?


答案 1

是的,会的。为什么不应该呢?

因为子项实际上是父项的实例。如果只想对孩子执行操作,则应检查

if (child instanceof Child){
}

但是,您应该记住Scott Meyers的《有效C++》中的以下声明:

“每当你发现自己在写这样的代码时,'如果对象是T1类型,那就做点什么,但如果它是T2类型,那就做点别的事情,'”打自己一巴掌。

我认为这也适用于这种情况。如果要根据引用的对象所属的类类型来执行某些操作,以下代码结构应该可以帮助您。

注意:我还没有编译它。

class Parent {
    public void doSomething() {
        System.out.println("I am the Parent, and I do as I like");
    }
}
 
class ChildA extends Parent {
    public void doSomething() {
        System.out.println("I am a child named A, but I have my own ways, different from Parent");
    }
}
 
class ChildB extends Parent {
    public void doSomething() {
        System.out.println("I am a child named B, but I have my own ways, different from my Parent and my siblings");
    }
}
 
public class Polymorphism101 {
 
    public static void main(String[] args) {
 
        Parent p = new Parent();
        p.doSomething();
 
        p = new ChildA();
        p.doSomething();
 
        p = new ChildB();
        p.doSomething();
 
    }
 
}

编辑:一个更好的例子

您可能正在开发绘图应用程序。绘制任何类型的形状的应用程序。在这种情况下,您应该有一个抽象类型。Shape

用于以下目的;绘制所有形状;列出所有形状;查找形状或删除形状,您需要有一个形状列表。由于列表是父类型,因此它可以存储任何形状。

接口/抽象类/虚拟类应具有抽象/纯虚函数 。因此,在您的DrawToDeviceLoop中,您只需调用每个形状,就不需要检查它是什么形状。ShapeDraw()Draw()

该接口可以有一个抽象实现,它可以具有形状名称或id作为数据成员,以及GetName,Cleanup和其他具有所有形状通用的功能的函数。ShapeAbstractShape

请记住,抽象类型无法实例化,因此本身也无法实例化,因为它也无法绘制。Shape

编辑2:多态性和异常处理 - user1955934询问“检查异常类怎么样” 对于异常处理,有关多态性的最佳实践是:

  1. 首选(抛出)特定的异常 - 例如,抛出一个NumberFormatException而不是FregalArgumentException
  2. 首先捕获最具体的异常 - 例如,如果您首先捕获非法参数异常,则永远不会到达应处理更具体的 NumberFormatException 的捕获块,因为它是 IllegalArgumentException 的子类。

因此,它本质上是相同的,如果需要以不同的方式处理异常,则应定义子/特定类,并应捕获特定异常(未检查实例)

了解有关异常处理的更多最佳做法。请参阅 Java 中处理异常的 9 个最佳实践和异常的最佳实践 (C#)

编辑3:我承认这个规则有例外

因此,我正在使用一个遗留代码(用C++编写),该代码大多是在大约15年前编写的,他们总是检查子类以执行某些操作。我被要求添加一些具有相同逻辑的代码,我告诉我的经理(他也是Dev)我不能这样做,指出这个答案,然后我们讨论并接受了这个例外规则。在我们的例子中,这个父类自2000年以来只有2个孩子,我们没有看到任何孩子在不久的将来被添加,核心代码限制增长,我们决定在没有添加子类并且当前数字仅为2的情况下,检查类型更有效, 特别是当代码就是这样编写的,从那以后。

不过,这种检查的实例也不多,父级主要实现复杂的功能,它的存在更多地是为了共享代码,然后专门化/区分它们。


答案 2

如果实例是子类,则将返回 true...

文档实例