为每个循环使用Base类类型或Derived类类型

时间:2014-08-20 21:20:00

标签: java casting

假设我有这段代码:

class ABC 
{
   List<Orange> list;
   Orange orange;

   public static Fruit getFirstOrange()
   {
      list = getFruits();
      for(Fruit fruit:list)    // Here is the confusion
      {
        if(fruit.name.equals("orange")
        orange = (Orange) fruit;
        break;
      }
   }

   public List<Orange> getFruits()
   {
      return new List<orange>();
   }
}

所以在每个循环的上面代码中,我应该在这种情况下使用Fruit或Orange类型。

      for(Fruit fruit:list)    // Here is the confusion
      {
        if(fruit.name.equals("orange")
        orange = (Orange) fruit;
        break;
      }

     *OR*

      for(Orange fruit:list)    // Here is the confusion
      {
        if(fruit.name.equals("orange")
        orange = fruit;
        break;
      }

所以上面哪一个是正确的做法。我认为既然我的列表包含了橙色,我就不应该在每个循环中使用Fruit类型。

3 个答案:

答案 0 :(得分:2)

鉴于

List<Orange> fruit;

然后for (Orange orange : fruit)将循环遍历是橙色的每个水果,因为水果列表只能包含橙子。这是 迭代列表的最佳方式,因为它应用 最具体的类型来统一项目。

现在,考虑何时使用超类型

for (Fruit someFruit : fruit)   // an Orange is also a Fruit, okay
   someFruit.separateSlices();  // whoops! not all Fruit have slices
}

for (Object anyObject : fruit)  // an Orange is also an Object, okay
   anyObject.eat();             // whoops! can't eat random Objects
}

虽然可以使用强制转换,因为所有项目都保证为橙色,但它不会简单地在增强的for循环中改进类型。此外,在for循环中使用特定类型可以防止与某些类似的类型相关的错误。考虑一下,

List<Fruit> fruit;            // now really fruit
for (Orange orange: fruit) {  // error: incompatible types, won't compile
                              // as not all Fruit are Oranges
   // ..
}

但是演员,

List<Fruit> fruit = new ArrayList<Fruit>();
fruit.add(new Orange());
fruit.add(new Apple());               // valid, an Apple is also a Fruit
for (Fruit someFruit: fruit) {        // still most specific: Fruit, not Object
   Orange orange = (Orange)someFruit; // runtime ClassCastException on Apple
}

因此,我的建议是使用适用于问题域的最具体/精炼类型。在原始问题的情况下,从一开始就将每个项目键入橙色;或者修改使用List<Orange>存储各种不同水果的假设。

答案 1 :(得分:1)

如果listList<Orange>,那么您当然应该使用for (Orange o : list),因为它是列表元素的类型。


如果listList<Fruit>,那么您应该使用for (Fruit f : list)。这样做的原因是列表能够容纳其他类型的元素,例如AppleBanana(如果您实现了它们)。因此,您应该使用最近的超类,Fruit

答案 2 :(得分:1)

如果您的列表是橙色类型,那么您应该使用橙色。你的定义是

List<Orange> list;

所以你的循环可以是

for(Orange o : list) {}

如果您的列表是Fruit类型,那么您将在循环中使用Fruit,并在适当和必要时进行转换。