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
对象,该对象小于(?)而不是B
(B extends A
)。
为什么会出现ArrayStoreException: A
错误?它是如何工作的?
答案 0 :(得分:4)
您可以在该对象内存储对象的子类。即B
可以存储在A
中,但A
是B
类型的超类。基本上,继承链中类X
下面的任何类都可以称为类型X
,但继承链中类X
之上的任何类都不能称为类型{{ 1}}。
您的示例
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
只能称为X
。 (或者是子类的子类。它是一个递归定义)。
让我们使用一些英语术语
让我们拥有Y
和A
,而不是B
和Item
。
Book
现在,说:
是有道理的public class Item {}
public class Book extends Item {}
说:
是没有意义的Item b = new Book(); // All Books are items.
答案 1 :(得分:1)
抛出表示已尝试存储错误 对象类型为对象数组。例如,以下内容 代码生成一个ArrayStoreException:
Object x[] = new String[3];
x[0] = new Integer(0);
答案 2 :(得分:1)
“我的动物数组将仅包含蝴蝶(A[] tab = new B[10];
)。在数组中添加一个新动物(tab[0] = new A();
)。”
如何确定插入的动物是蝴蝶?
答案 3 :(得分:1)
java中的拇指规则是超类引用变量可以指向子类对象而不是反之亦然,如果你考虑一下,那么父类可以指向子类对象是有意义的。 List list = new ArrayList()
答案 4 :(得分:1)
因为如果B扩展A,B具有所有A特征(属性,方法等),加上他自己的。
然后每个B也是A,而A(缺少B的特征)不是B。
答案 5 :(得分:1)
这归结为分层类型系统的最基本属性,即 Liskov替换原则:只要允许A的实例,也允许其任何子类型的实例。数组不是特例。
答案 6 :(得分: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