我有一个类(我们称之为Vehicle)和一个子类(Car)。两者的实例都存储在一个 ArrayList 中。Car 有一个不是从 Vehicle 继承的方法 doStuff()。我想对 ArrayList 中的每辆车做 doStuff()。这是我想出的最简单的解决方案:
vehicleList = new ArrayList<Vehicle>();
roster.add(new Vehicle());
roster.add(new Car());
for (Vehicle v: vehicleList){
if (v instanceof Car){
((Car) v).doStuff();
}
}
但我觉得有一种更简单的方法可以做到这一点。因此,如果您可以提供更简单的解决方案,请提前感谢。
如果您的列表被声明为 List<Vehicle>
,那么这是正确的方法 - 如果不检查单个项目是Truck
、Car
或其他东西,你就无法判断。
如果Vehicle
拥有该方法有意义,您可以在那里声明doStuff
,默认情况下让它不执行任何操作,并在Car
中放置一个真正的实现。不过,这通常是设计不佳的标志。
另一种选择是获取List<Car>
,因此您不必检查列表中的每个项目的类型。 您也可以将doStuff
作为接口CanDoStuff
的一部分,因此它不是您要检查Car
- 这样您也可以轻松地将其应用于其他类。
"最简单的"解决方案是在车辆中实现doStuff(),并且让它什么都不做。 例如
public void doStuff(args) { ; }
然而,这通常是设计不佳的暗示。 可能是个好主意,也可能是坏主意。
有 2 个选项:
-
将
doStuff()
添加到Vehicle
(默认 impl 可以是"不执行任何操作") -
类似于您拥有的东西。确定特定
Vehicle
是否可以"做事"的某种方法。你可以在Vehicle
类中有一个canDoStuff()
方法(仍然需要一个强制转换,基类开始"知道太多"。你可以Car
实现一个CanDoStuff
接口 - 如果有一天你可能有一个也可以做东西的Van
,那么比直接使用Car
要好一些。
将类似的类型存储在一起。那么你就不会有这个问题了。问问自己,如果它们的行为都不同,为什么将所有战车存储在一个列表中。结束。:)
您可以做一些棘手的事情,例如创建一个"过滤迭代器",它基本上根据类类型返回过滤的子列表。 这是一个高级主题,但是如果您的项目具有非常突出的此列表方法,则可以编写一次该过滤器并到处使用它。