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