使用Java中的foreach循环派生类

时间:2013-10-10 04:08:14

标签: java foreach

我有一个类派对,派生类动作,喜剧和戏剧。我有一系列不同的电影叫做rentedMovies。

当我使用简单的for循环遍历数组时,

for(int i = 0; i < rentedMovies.lenght; i++){
  ..Do something..
}

IntelliJ IDE建议我可以将此循环更改为foreach。

for(Movie movie: rentedMovies){
 ..Do something..
}

但这不是暗示我的所有电影元素都将被视为Movie类的对象而不是派生类的对象吗? 这是IDE的错误建议还是我不正确?感谢。

4 个答案:

答案 0 :(得分:2)

rendedMovies声明类似于

这一事实已经暗示了这一假设
ArrayList<Movie> rentedMovies

因此,您将能够了解集合中包含的对象的最具体信息是它们的类型为Movie。你被迫在Java中这样做,因为泛型集合只能有一个特定的类型。为了能够将所有子类添加到集合中,您必须提供一个公共超类。

将对象添加到类时,类型信息会丢失。例如:

Comedy comedy = new Comedy();
rentedMovies.add(comedy);
Comedy comedy2 = rentedMovies.get(0); // compile error: get returns Movie
Movie movie = rentedMovie.get(0); // correct

简而言之,如果您不需要当前电影的索引,则您的片段是等效的。 请注意for-each语句适用于引擎盖下的迭代器,因此如果您要修改循环内的集合,那么您必须注意您正在做的事情

如果您想从集合中获取元素的特定信息,那么您必须自己进行下传(并且忘记编译类型安全而不用手动检查),例如:

public Comedy asComedy() {
  return this instanceof Comedy ? (Comedy)this : null;
}

但是如果你需要这样做,那么你应该重新设计继承。也许你可以完全在Movie的子类中移动行为,这样你就不需要知道特定的类型,只需要调用公共接口的方法。

答案 1 :(得分:1)

我认为你的rentedMovies被声明为Movies[],所以原来的for循环仍将它们作为电影对象。

如果你想使用子类的特定方法,那么你将不得不抛出任何一种情况。

使用(int i = 0; i < rentedMovies.lenght; i++)的实现的好处是,如果你不需要循环已经使用的数组(然后Intellij不会给你这个警告)或相对于当前对象的索引位置,那么你有索引< / p>

答案 2 :(得分:1)

如果你有一个不同类型的数组,那么Array变量的类型应该是超类。

无论如何,如果你要在循环中搜索特定类型的电影,你必须进行明确的检查(不是很好的设计)。

所以你使用哪个循环真的没什么区别......因为每个循环都会更简单,没有任何缺点。

答案 3 :(得分:1)

如果你在一个数组中有“动作,喜剧和戏剧”,则rentedMovies必须是“电影”类。因此,如果你在for循环中迭代它们,你就像“电影”一样迭代它们,而不是像“动作,喜剧或戏剧”。

建议的IDE迭代与您使用的相同,但如果您决定将数组更改为List,可能会更直观并可用于很多类(如List)。