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

Posted

技术标签:

【中文标题】如果是父实例,instanceof 是不是返回 true?【英文标题】:Does instanceof return true if instance of a parent?如果是父实例,instanceof 是否返回 true? 【发布时间】:2011-09-12 08:11:33 【问题描述】:

我有一个扩展 Parent 的类 Child

Parent child = new Child();

if (child instanceof Parent)
    // Do something

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

【问题讨论】:

【参考方案1】:

Yes,会的。为什么不呢?

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

if (child instanceof Child)

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

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

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

注意:我还没有编译。

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

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

Shape接口/抽象类/虚拟类应该有一个抽象/纯虚拟函数Draw()。因此,在您的 DrawToDeviceLoop 中,您只需为每个形状调用 Draw(),您无需检查它是什么形状。

Shape 接口可以有一个abstract 实现AbstractShape,它可以有形状名称或ID 作为数据成员,以及GetName、Cleanup 和其他具有所有形状通用功能的函数。

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

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

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

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

了解有关异常处理的更多最佳实践。见9 Best practices to handle exception in Java和Best practices for exceptions (C#)

【讨论】:

但是我在运行时确定了对象类型,我需要定义一个父引用来保存所有类型的子对象。我怎么能以另一种方式做到这一点? @user479129:您可以在 parent 类型的引用中保存对任何父级的子级的引用。也就是说,如果有class Parent class ChildA extends Parentclass ChildB extends Parent 那么你可以使用Parent p 来引用ChildAChildB 类型的对象,但我不明白你的意思通过其他方式圆形。 我需要控制对象 p 是其子对象的类型,而不是父对象。在某些情况下,它可能是父类型,所以我需要检查它是否正是我想要的类型。这就是我想要的。我希望它清楚 我也想要一个改进的答案,这对于使用 Frame.getComponents() 而不是单独处理每一个非常有用。 @JasonK。你的意思是更好的例子吗?【参考方案2】:

instanceof 如果是子类,则返回 true...

instanceof Documentation

【讨论】:

现在,这个问题总是正确的。谢谢【参考方案3】:

当然它会返回 true,因为 child 是 parent 的一个实例

【讨论】:

是的,如果 child 是 parent(或实现)的实例,java any 返回 true。【参考方案4】:

是的。只要引用(instanceof 表达式的左侧)可以转换为 ReferenceTypeinstanceof 表达式右侧的类型),instanceof 就会为真。这对于与其父类相关的子类来说是正确的:

Child child = new Child();
Parent parent = (Parent) child; //works!
assert child instanceof Parent; //true

来自The Java Language Specification, Java SE 9 Edition:

15.20. Relational Operators ...RelationalExpression instanceof ReferenceType

15.20.2. Type Comparison Operator instanceof ... 在运行时,如果 RelationalExpression 的值不是 null 并且引用可以转换为 ReferenceType,则 instanceof 运算符的结果是 true没有提出ClassCastException。否则结果为false

【讨论】:

以上是关于如果是父实例,instanceof 是不是返回 true?的主要内容,如果未能解决你的问题,请参考以下文章

使用instanceof操作符判断对象类型及方法的重载

instanceof操作符

instanceof 操作符 接口 多态

instanceof, isinstance,isAssignableFrom的区别

instanceOf与isInstance()方法之间的区别

实现instanceof功能的函数