如何在没有 instanceof 或 getClass 的情况下访问 class 特定方法

How to access class specific methods without instanceof or getClass

假设我有以下接口和实现:

interface Weapon{
    int attack();   
}

public class Sword implements Weapon {

    //Constructor, and Weapon interface implementation
    //...
    public void wipeBloodfromSword(){}
}


public class ChargeGun implements Weapon {
    //Constructor, and Weapon interface implementation  
    //...
    public void adjustlasersight(){}
}

并像这样存储它们:

List<Weapon> weaponInventory = new ArrayList<Weapon>();
weaponInventory.add(new Sword());
weaponInventory.add(new ChargeGun());

问题:

鉴于它们存储在 List<Weapon> 中,我显然只能访问 Weapon interface 中声明的方法。如果 downcasting 并应避免使用 ,我将如何访问 class 特定方法 wipeBloodfromSword()adjustlasersight()?

可能的解决方案:

鉴于调用攻击方法前后都有动作,我可以这样重写我的界面:

interface Weapon{

   //Can reload a weapon, adjust a laser sight 
   //do anything to the weapon to prepare for an attack
   void prepareWeapon(); 
   int attack();
   //Not sure of a more proper name, 
   //but you can wipe blood off sword  or take off silencer 
   void postAttackActions();
}

尽管我控制着这个爱好项目,但我可能 运行 无法更改 interface,而 interface 重新write 可能会解决这个特定的问题,如果我必须让 interface 保持原样,我该怎么办?

您可以将 List 项目类型转换为 Sword 或 ChargeGun,然后调用相应的方法

((Sword) weaponInventory.get(0)).wipeBloodfromSword();

由于您有一组固定的 类,您可以使用访问者模式,它无需显式向下转换即可工作。

class WeaponVisitor {
   void visit(Sword aSword) { }
   void visit(ChargeGun aGun) { }
}

// add accept method to your Weapon interface
interface Weapon {
  ...
  void accept(Visitor v);
}

// then implement accept in your implementing classes
class Sword {
...
   @Override
   void accept(Visitor v) {
      v.visit(this); // this is instanceof Sword so the right visit method will be picked
   }
}

// lastly, extend Visitor and override the methods you are interested in
class OnlySwordVisitor extends Visitor {
     @Override void visit(Sword aSword) {
      System.out.println("Found a sword!");
      aSword.wipeBloodfromSword();
     }
 }