如果是父实例,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 Parent
和class ChildB extends Parent
那么你可以使用Parent p
来引用ChildA
或ChildB
类型的对象,但我不明白你的意思通过其他方式圆形。
我需要控制对象 p 是其子对象的类型,而不是父对象。在某些情况下,它可能是父类型,所以我需要检查它是否正是我想要的类型。这就是我想要的。我希望它清楚
我也想要一个改进的答案,这对于使用 Frame.getComponents() 而不是单独处理每一个非常有用。
@JasonK。你的意思是更好的例子吗?【参考方案2】:
instanceof 如果是子类,则返回 true...
instanceof Documentation
【讨论】:
现在,这个问题总是正确的。谢谢【参考方案3】:当然它会返回 true,因为 child 是 parent 的一个实例
【讨论】:
是的,如果 child 是 parent(或实现)的实例,java any 返回 true。【参考方案4】:是的。只要引用(instanceof
表达式的左侧)可以转换为 ReferenceType(instanceof
表达式右侧的类型),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, isinstance,isAssignableFrom的区别