父数组中的Java子引用类型

时间:2018-08-02 15:52:34

标签: java polymorphism

对于以下问题,

假设在

的单元格中引用的对象
ArrayList<Polygon> pentagonGroup

是五角大楼类型。如果您以后引用该对象,它将具有什么类型?

答案是什么?

我尝试在IDE中玩耍,并且在执行以下操作时,即使将子对象放置在“父对象”列表中也被标识为“子对象”。

Child c = new Child();
ArrayList<Parent> pa = new ArrayList<Parent>();
pa.add(c);
Class cls = pa.get(0).getClass();
System.out.println(cls.getName());

当无法使用特定于Child对象的方法而不将其向下转换回Child时,这似乎有点奇怪。

System.out.println(pa.get(0).getChildMessage()); // invalid
System.out.println(((Child)pa.get(0)).getChildMessage()); // valid

鉴于我的结果,第一个问题的答案将是(五角大楼)。正确吗?

编辑:

所以我实际上仍然不确定上面提出的第一个问题;答案是多边形还是五角大楼?

2 个答案:

答案 0 :(得分:2)

在运行时,您可以获取pa.get(0)的类型:

Class cls = pa.get(0).getClass();
System.out.println(cls.getName());

在编译阶段,编译器仅知道pa.get(0)Parent,因此如果不进行向下转换,则无法调用pa.get(0).getChildMessage()。是为了类型安全。

实际上,您可以将任何对象强制转换为Child进行编译,

Object o = new Object();
System.out.println(o.getChildMessage());

但是它将在运行时引发强制转换

答案 1 :(得分:0)

假设Child扩展了Parent,就编译器而言,ArrayList由Parent对象组成。因此,当您从列表中获得一个值时,它就是父级。在您的情况下,它也是一个孩子,但在一般情况下可能不是。

请记住,Java与具有动态绑定的Groovy不同,因此,如果Parent没有getChildMessage()方法,则它没有可以分配给它的方法。因此,您可以选择在Parent中定义getChildMessage()方法(可能返回一个空字符串或抛出异常),然后在Child中覆盖它,或者像您所做的那样向下转换,但是请确保首先使用instanceof作为Child,例如