我正在尝试将子类对象数组分配给它的超类。程序编译成功,但我得到ArrayStoreException
。我知道数组父和子是对同一个数组的引用,但至少我不能访问方法func
吗?
class Pclass
{
Pclass()
{
System.out.println("constructor : Parent class");
}
public void func()
{
System.out.println("Parent class");
}
}
class Cclass extends Pclass
{
Cclass()
{
System.out.println("Constructor : Child class");
}
public void func2()
{
System.out.println("It worked");
}
public void func()
{
System.out.println("Common");
}
}
public class test
{
public static void main(String ab[])
{
Cclass[] child = new Cclass[10];
Pclass[] parent = child;
parent[0]=new Pclass();
parent[0].func();
}
}
答案 0 :(得分:4)
你不能这样做:
Cclass[] child = new Cclass[10];
Pclass[] parent = child;
parent[0]=new Pclass();
你应该尝试这样做:
Cclass[] child = new Cclass[10];
Pclass[] parent = child;
parent[0]=new Cclass();
那是因为,你首先将Pclass数组分配给只能有Cclass对象的子引用,然后你试图将Pclass对象分配给父引用,这是不允许的!
请注意,当你编写新的Cclass时,你在堆上创建了一个Cclass对象会发生什么,尽管Cclass对象在数组中是null但现在它们只接受Cclass对象或它的子类&#39 ; s对象
所以分配Pclass对象是非法的!
获取运行时异常而非编译时间的原因:
编译器只检查这些类是否在同一个继承层次结构中,因为它们在同一层次结构中会得到运行时异常。
答案 1 :(得分:1)
如果您阅读了ArrayStoreException
的规范,就会发现它被抛出to indicate that an attempt has been made to store the wrong type of object into an array of objects.
您创建了Cclass
数组的实例,因此只有Cclass
(或其子类)的实例可以存储在此数组中。将该实例的引用存储在Pclass[]
类型的变量中的事实不会改变它。
答案 2 :(得分:0)
虽然对数组的引用是Pclass
,但是它们引用的数组对象的类型为Cclass
(您实例化了对象new Cclass[]
。您无法通过以下方式更改对象的类型有一个不同类型的变量引用它)。您无法在Pclass
数组中存储Cclass
对象。
相反,如果可能,您应该使用子类型创建对象:
parent[0] = new Subclass();
答案 3 :(得分:0)
您实际上在行Cclass[] child = new Cclass[10];
中实例化了一个子类对象,当您使用new Pclass();
实例化父对象时,您创建了父对象。当您将其分配给子对象时,会发生向下转换在运行时它失败,因为你试图将父对象存储到子reference.Hence它抛出ArrayStoreException
,即你试图将错误类型的对象存储到一个对象数组。