Java:如何访问泛型对象列表中类的独有方法
子类独有方法调用的优化方案
场景说明
我有Equipment和Product两个类,均为Item类的子类。现在把导入的设备与产品存储在ArrayList<Item>集合中,需要遍历该集合并调用Equipment和Product各自的独有方法。我知晓使用instanceof通常属于不良实践,以下是我尝试的简化实现代码:
for(Item i: listOfItems){ if(i.itemType instanceof Equipment){ i.getEquipmentVin(); } }
优化方案(替代instanceof)
- 多态实现(最推荐):在父类
Item中定义抽象方法,子类各自实现对应逻辑。比如新增一个process()抽象方法,Equipment实现时调用自身的getEquipmentVin(),Product实现时调用自己的独有方法。这样遍历集合时直接调用i.process()即可,完全无需判断类型。
示例代码:abstract class Item { public abstract void process(); } class Equipment extends Item { public String getEquipmentVin() { return "设备VIN码"; } @Override public void process() { getEquipmentVin(); // 可在此添加设备专属业务逻辑 } } class Product extends Item { public String getProductSerial() { return "产品序列号"; } @Override public void process() { getProductSerial(); // 可在此添加产品专属业务逻辑 } } // 遍历调用 for(Item i : listOfItems) { i.process(); } - 访问者模式(适用于父类无法修改的场景):如果不能改动
Item类,或者需要在外部集中处理不同子类的逻辑,可以采用访问者模式。定义访问者接口,子类实现接受访问的方法,将自身传递给访问者进行处理。
示例代码:interface ItemVisitor { void visit(Equipment equipment); void visit(Product product); } abstract class Item { public abstract void accept(ItemVisitor visitor); } class Equipment extends Item { public String getEquipmentVin() { return "设备VIN码"; } @Override public void accept(ItemVisitor visitor) { visitor.visit(this); } } class Product extends Item { public String getProductSerial() { return "产品序列号"; } @Override public void accept(ItemVisitor visitor) { visitor.visit(this); } } // 使用时的处理逻辑 ItemVisitor handler = new ItemVisitor() { @Override public void visit(Equipment equipment) { equipment.getEquipmentVin(); // 执行设备相关处理逻辑 } @Override public void visit(Product product) { product.getProductSerial(); // 执行产品相关处理逻辑 } }; for(Item i : listOfItems) { i.accept(handler); } - 若必须使用
instanceof(不推荐):注意你原代码存在错误,i.itemType instanceof Equipment应改为i instanceof Equipment,且必须强制转型后才能调用子类独有方法:for(Item i: listOfItems){ if(i instanceof Equipment){ Equipment equipment = (Equipment) i; equipment.getEquipmentVin(); } else if(i instanceof Product) { Product product = (Product) i; product.getProductSerial(); } }
内容的提问来源于stack exchange,提问作者JC Howell
相关产品推荐
相关产品推荐

