基本上标题是什么,但有些细节。我有一个带有几个SubClasses的SuperClass。我需要一个ArrayList来保存两种类型的子类,因此需要类型为SuperClass的ArrayList。我尝试使用getQuantity()
访问Subclass1的ArrayList.get(0).getQuantity();
方法(假设索引0的类型为SubClass1)。我收到错误:类型SuperClass的getQuantity未定义。
当放入SuperClass ArrayList时,SubClass对象是否不保留其属性?如果他们确实保留了他们的属性,我该如何访问它们?
答案 0 :(得分:5)
对象本身仍然是subclass
,但是当你将它们从集合中取出时它只知道superclass
所以它无法告诉你哪个是哪个,它必须选择共同点。
如果您确切知道特定索引包含Subclass
类型的对象,则可以将其强制转换:
Subclass myObject = (Subclass) list.get(0);
System.out.println(myObject.getQuantity());
它应该有用。
更安全的方法需要测试对象是否真的如你所想:
SuperClass myObject = list.get(0);
if ( myObject instanceof Subclass) {
Subclass mySubObject = (Subclass) myObject;
System.out.println(mySubObject.getQuantity());
}
如果对象不是Subclass
类型,则第一个示例引发异常,第二个示例因为之前的测试而无法确认。
您需要了解的是SuperClass myObject = list.get(0)
不是对象本身,而是访问内存中对象的引用。把它想象成一个允许你控制对象的遥控器,在这种情况下,它不是一个功能齐全的遥控器,因为它没有显示你的所有对象都能做到的,所以你可以切换到更好的一个(如{ {1}})能够访问所有功能。
我肯定会推荐Head First Java book因为它非常详细地介绍了这些内容(我从那里偷走了这个远程示例)。
答案 1 :(得分:0)
所有对象都保留自己的类标识,但使用ArrayList
的代码并不直接知道它。就它而言,ArrayList
只保存对SuperClass
- 类型对象的引用,并且它只能在它从它检索的对象上调用SuperClass
的方法。
调用代码可以使用instanceof
或类似技术来查明集合中的特定对象是否属于子类型,但这通常是不好的做法,因为它通常表示混合不同抽象层次。通常认为合理的一种情况是,如果子类具有一些可选的高性能特性,调用者可以利用该特性(并且测量已确定值得使代码复杂化);一个例子可能是虽然List
的{{1}}方法没有性能保证,但某些实现(如get()
)也实现了ArrayList
,这表明没有性能损失以任何顺序使用RandomAccess
。
答案 2 :(得分:0)
当你有一些ArrayList并且你用扩展SuperClass的东西填充它时,你必须检查instanceof并强制转换以获取特定于这些子类的方法。
示例:
ArrayList<Animal> animals = new ArrayList<Animal>;
animals.add(new Duck());
animals.add(new Cow());
animals.add(new Horse());
for (Animal animal : animals)
if (animal instanceof Horse) {
Horse horse = (Horse)animal;
horse.gallop();
}