0
class A {}
class B extends A {}

嗨,我正在学习 Java,我试图理解为什么会这样:

A[] tab = new A[10];
tab[0] = new B();

而不是这个:

A[] tab = new B[10];
tab[0] = new A();

这一行A[] tab = new B[10];意味着编译器在内存中为 B 预订了 10 个位置。tab[0] = new A()设置tab[0]等于一个小于 (?) 小于( ) 的新A对象。BB extends A

为什么会出现ArrayStoreException: A错误?它是如何工作的 ?

4

7 回答 7

4

您可以在该对象内存储对象的子类。ieB可以存储在 中A,但是A是 type 的超类B。基本上,继承链中 class 之下X的任何类都可以称为 type X,但继承链中 class 之上X的任何类都不能称为 type X

你的例子

A[] tab = new A[10]; // Perfectly fine. Equal objects.
tab[0] = new B(); // B is a subclass of A, so this is allowed.

A[] tab = new B[10]; // Same principle as above, B is a subclass of A
tab[0] = new A(); // A is a SUPERCLASS of B, so it can not be referred to as A

简而言之,X只能称为Y,ifX是 的子类Y。(或子类的子类。这是一个递归定义)。

让我们使用一些英语术语

代替Aand B,让我们拥有Itemand Book

public class Item {}

public class Book extends Item {}

现在,说得有道理:

Item b = new Book(); // All Books are items.

说:

Book b = new Item(); // All items are definitely not books.
于 2013-06-04T09:25:49.843 回答
1

根据文档

抛出以指示已尝试将错误类型的对象存储到对象数组中。例如,以下代码生成 ArrayStoreException:

Object x[] = new String[3]; 
x[0] = new Integer(0);
于 2013-06-04T09:26:55.067 回答
1

“我的 Animal 数组将只包含蝴蝶 ( A[] tab = new B[10];)。在数组 ( ) 中添加一个新的 Animal tab[0] = new A();。”

如何确定插入的动物是蝴蝶?

于 2013-06-04T09:27:24.513 回答
1

java中的经验法则是超类引用变量可以指向子类对象,反之亦然,如果您考虑一下,父类可以指向子类对象是有道理的。列表列表 = 新的 ArrayList()

于 2013-06-04T09:27:59.990 回答
1

因为如果 B 扩展 A,B 具有 A 的所有特征(属性、方法等),加上他自己的。

那么每个 B 也是 A,而 A(缺少 B 的特征)不是 B。

于 2013-06-04T09:28:03.547 回答
1

这归结为分层类型系统的最基本属性,即Liskov 替换原则:在允许 A 的实例的任何地方,也允许其任何子类型的实例。数组不是特殊情况。

于 2013-06-04T09:28:11.823 回答
1

鉴于:

class A { }

class B extends A { }

我们有:

A [] a = new A [10]; // can store A or B objects

A [] b = new B [10]; // can only store B objects
于 2013-06-04T09:39:48.107 回答