Java如何从WarMachine集合中调用Flies接口方法获取最大飞行时速的Airoplane
问题背景
给定的接口、类与主结构定义如下(已对原代码中缺失的大括号、类名拼写笔误做标注修正):
// 接口定义 interface Driveable{ public void drive(); } interface Flies{ public void isFlying(); public Integer fliesKmPerHour(); } // 抽象类与子类定义 abstract class WarMachine{ // 省略通用属性与方法实现 } // 原代码写作Vehlice,为Vehicle(地面载具)的拼写笔误 class Vehicle extends WarMachine implements Driveable{ // 省略地面载具的专属逻辑 } class Airoplane extends WarMachine implements Driveable, Flies{ // 省略飞行器的专属逻辑 } // 主类定义 public class War { public ArrayList<WarMachine> warMachineArrayList; public War() { warMachineArrayList = new ArrayList<>(); } // 待实现的目标方法:返回集合中飞行速度最高的飞机实例 public Airoplane getMaxAiroplane(){ Airoplane airoplane = null; // 待补全逻辑 } }
为什么不能直接从集合元素调用fliesKmPerHour()
本质是Java静态类型检查的规则限制:
你存储元素的warMachineArrayList泛型声明为父类WarMachine,拿到每个集合元素时,编译器仅知道它是一个战争机器,无法确认它具体是地面载具、还是可飞行的飞机。而fliesKmPerHour()是定义在Flies接口、仅由Airoplane类实现的方法——父类WarMachine本身既未实现Flies接口,也没有声明这个方法,直接通过父类引用调用该方法无法通过编译。
实现思路
要访问这个方法,必须先对集合元素做类型校验,确认它确实是Airoplane实例后,再强转为对应的类型,才能正常调用方法。具体逻辑:
- 遍历集合中所有
WarMachine元素 - 用
instanceof判断元素是否为Airoplane类型,过滤掉Vehicle等其他子类实例,避免运行时类型转换异常 - 对校验通过的元素强转为
Airoplane类型,读取其fliesKmPerHour()返回值 - 遍历过程中记录速度最高的实例,遍历完成后返回该实例
基础写法实现(兼容所有Java版本)
public Airoplane getMaxAiroplane(){ Airoplane maxPlane = null; Integer maxSpeed = Integer.MIN_VALUE; for (WarMachine machine : warMachineArrayList) { // 类型校验,仅处理飞机实例 if (machine instanceof Airoplane) { Airoplane currentPlane = (Airoplane) machine; Integer currentSpeed = currentPlane.fliesKmPerHour(); // 空值保护,避免接口返回null时触发空指针 if (currentSpeed == null) { continue; } // 更新最高速度与对应实例 if (currentSpeed > maxSpeed) { maxSpeed = currentSpeed; maxPlane = currentPlane; } } } return maxPlane; }
Java 8+ 流API简化写法
逻辑与基础写法完全一致,代码更简洁:
public Airoplane getMaxAiroplane(){ return warMachineArrayList.stream() // 过滤出飞机实例 .filter(Airoplane.class::isInstance) // 类型强转 .map(Airoplane.class::cast) // 过滤掉速度为空的实例 .filter(plane -> plane.fliesKmPerHour() != null) // 按飞行速度取最大值 .max(Comparator.comparingInt(Airoplane::fliesKmPerHour)) // 无符合条件的实例时返回null .orElse(null); }
踩坑提醒
- 绝对不能跳过类型校验直接强转,只要集合中存在
Vehicle实例,程序运行时会直接抛出ClassCastException Flies接口中fliesKmPerHour()返回的是Integer包装类型,部分实现可能返回null,直接拆箱对比会触发空指针,必须加空判断- 如果后续新增其他可飞行的战争机器,可将类型判断条件从“是否为Airoplane”调整为“是否实现了Flies接口”,无需修改核心业务逻辑
内容的提问来源于stack exchange,提问作者user15284992
相关产品推荐
相关产品推荐

