Java:将子类数组对象分配给超类数组对象

6

我试图将子类对象数组分配给其父类。程序成功编译,但我收到了一个 ArrayStoreException异常。我知道数组parent和child是对同一数组的引用,但我至少应该能够访问方法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();
    }
}

作为合适的 Java 代码,你在访问控制上很有选择性。为了编写统一的代码,你需要添加一些 public 关键字(还要修复那些到处都是的空格...记得阅读 http://stackoverflow.com/help/how-to-ask - 其中“记得校对”这部分不是闹着玩的。许多人,包括你在内,都会忘记这一点)。 - Mike 'Pomax' Kamermans
4个回答

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对象分配给父引用,这是不允许的!
看到了吗,当您编写new Cclass时,您在堆上创建了一个Cclass对象,虽然数组中的Cclass对象为空,但现在它们只接受Cclass对象或其子类的对象。
因此,分配Pclass对象是非法的!
运行时异常而不是编译时异常的原因:
编译器仅检查类是否在相同的继承层次结构中,由于它们在相同的层次结构中,所以会得到运行时异常。

OP知道他不能那样做 - 问题是为什么不能?你的替代建议与问题毫无关系。-1 - drew moore
@drewmoore 写完整个答案需要时间 :) - Sarthak Mittal
取消了负评,但您仍未真正回答这个问题。潜在的混淆是一个引用与值的问题。 - drew moore
因为编译器不会检查这一点,编译器检查的是这些类是否在同一个继承层次结构中,由于它们在同一个层次结构中,所以会出现运行时异常,我认为我也应该在答案中提到这一点 :) - Sarthak Mittal

1
如果你阅读ArrayStoreException的规范,你会发现它被抛出来“表示试图将错误类型的对象存储到对象数组中”。你创建了一个Cclass数组的实例,所以只能存储Cclass(或其子类)的实例在这个数组中。你将该实例的引用存储在Pclass[]类型的变量中并不改变这一事实。

0

尽管数组的引用是 Pclass,但你正在引用的数组对象的类型是 Cclass(你实例化了对象 new Cclass[]。你不能通过具有不同类型的变量引用它来更改对象的类型)。你不能将 Pclass 对象存储在 Cclass 数组中。

相反,如果可能的话,应该使用子类型创建对象:

parent[0] = new Subclass();

0

在这行代码中:Cclass[] child = new Cclass[10];,你实例化了一个子类对象。当你使用new Pclass();实例化一个父类对象时,你创建了一个父类对象。当你将它分配给子对象引用时,向下转换发生在运行时,并且失败,因为你试图将父对象存储到子引用中。因此,它会抛出ArrayStoreException,也就是你试图将错误类型的对象存储到对象数组中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接