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

我有一个扩展 Parent 的类 Child.

I have a class Child that extends Parent.

Parent child = new Child();

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

这是返回真还是假,为什么?

Does this returns true or false, and why?

推荐答案

是,会的.为什么不呢?

因为 child 实际上是 Parent 的一个实例.如果您只想为孩子执行操作,则应检查

Because child is in fact an instance of Parent. If, you want to perform an operation only for a child you should check

if (child instanceof Child){
}

但是,您应该记住 Scott Meyers 的 Effective C++ 中的以下陈述:

However you should remember the following statement from Effective C++, by Scott Meyers :

"任何时候你发现自己在写作形式的代码如果对象是键入 T1,然后做某事,但如果它是 T2 类型,然后做点什么否则,"打自己一巴掌.

"Anytime you find yourself writing code of the form "if the object is of type T1, then do something, but if it's of type T2, then do something else," slap yourself.

我认为这也适用于这种情况.如果你想doSomething基于被引用对象所属的类类型,下面的代码结构应该可以帮助你.

which I think applies in this case too. If you want to doSomething based on what type of class the referenced object belongs to, the following code structure should help you with it.

注意:我还没有编译.

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();
 
    }
 
}

一个更好的例子

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

You could be developing a drawing application. An application that draws shapes of any kind. In that case, you should have an abstract type Shape.

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

For purpose(s) like; drawing all shapes; list all shapes; find a shape or delete a shape, you need to have a list of Shapes. Since the list is of a parent type, it can store any shapes.

Shape interface/abstract class/virtual class应该有一个abstract/pure virtual函数Draw().因此,在您的 DrawToDeviceLoop 中,您只需为每个形状调用 Draw(),您无需检查它是什么形状.

The Shape interface/abstract class/virtual class should have an abstract/pure virtual function Draw(). So, in your DrawToDeviceLoop, you just call Draw() for each shape, you never need to check what shape it is.

Shape接口可以有一个abstract实现AbstractShape,它可以有shape name或id作为数据成员和GetName、Cleanup等具有所有形状通用功能的函数.

The Shape interface can have an abstract implementation AbstractShape, which can have shape name or id as data members and GetName, Cleanup and other functions with functionality common to all shapes.

记住抽象类型不能被实例化,所以Shape本身不能被实例化,因为它也不能被绘制.

Remember an abstract type cannot be instantiated, so Shape itself cannot be instantiated, as it cannot be drawn either.

编辑 2:多态性和异常处理 - user1955934 询问如何检查异常类";对于异常处理,多态性的最佳实践是:

EDIT 2: Polymorphism and Exception Handling - user1955934 asked "What about checking for exception class" For exception handling the best practices with respect to polymorphism are:

  1. 更喜欢(抛出)特定异常 - 例如抛出 NumberFormatException 而不是 IllegalArgumentException
  2. 首先捕获最具体的异常 - 例如,如果您首先捕获 IllegalArgumentException,您将永远无法到达应处理更具体的 NumberFormatException 的 catch 块,因为它是 IllegalArgumentException 的子类.

所以,原则上是相同的,如果需要以不同方式处理异常,则应定义子/特定类,并且应捕获特定异常(未检查 instanceof)

So, its principally the same, if an exception needs to be handled differently, a child/specific class should be defined, and the specific exception should be caught (not checked instanceof)

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

To know more best practices on exception handling. See 9 Best practices to handle exception in Java and Best practices for exceptions (C#)

相关文章