有没有更简单的方法可以在 Java 中子类和超类的 ArrayList 上调用子类的方法



我有一个类(我们称之为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> ,那么这是正确的方法 - 如果不检查单个项目是TruckCar或其他东西,你就无法判断。

如果Vehicle拥有该方法有意义,您可以在那里声明doStuff,默认情况下让它不执行任何操作,并在Car中放置一个真正的实现。不过,这通常是设计不佳的标志。

另一种选择是获取List<Car>,因此您不必检查列表中的每个项目的类型。 您也可以将doStuff作为接口CanDoStuff的一部分,因此它不是您要检查Car - 这样您也可以轻松地将其应用于其他类。

"最简单的"解决方案是在车辆中实现doStuff(),并且让它什么都不做。 例如

public void doStuff(args) { ; }

然而,这通常是设计不佳的暗示。 可能是个好主意,也可能是坏主意。

有 2 个选项:

  1. doStuff()添加到Vehicle(默认 impl 可以是"不执行任何操作")

  2. 类似于您拥有的东西。确定特定Vehicle是否可以"做事"的某种方法。你可以在Vehicle类中有一个canDoStuff()方法(仍然需要一个强制转换,基类开始"知道太多"。你可以Car实现一个CanDoStuff接口 - 如果有一天你可能有一个也可以做东西的Van,那么比直接使用Car要好一些。

尽可能

将类似的类型存储在一起。那么你就不会有这个问题了。问问自己,如果它们的行为都不同,为什么将所有战车存储在一个列表中。结束。:)

您可以做一些棘手的事情,例如创建一个"过滤迭代器",它基本上根据类类型返回过滤的子列表。 这是一个高级主题,但是如果您的项目具有非常突出的此列表方法,则可以编写一次该过滤器并到处使用它。

最新更新