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或类似技术来确定集合中的特定对象是否属于子类型,但这通常是不好的做法,因为它通常表示不同抽象级别的混合。 通常认为合理的一种情况是,子类具有一些可选的高性能特性,调用者可以利用该特性(并且测量已确定值得使代码复杂化); 一个例子可能是,虽然Listget()方法没有性能保证,但是某些实现(如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(); }