【发布时间】:2017-10-25 00:01:16
【问题描述】:
假设我有以下接口和实现:
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 和 instanceof/getClass() 的使用应该避免,我将如何访问类特定方法 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 重写可能会解决这个特定问题,我应该怎么做如果我必须让interface 保持原样,该怎么办?
【问题讨论】:
-
“如果...我该怎么办”不是一个很好的问题类型。
-
如果您无法更改界面,则必须使用
instanceof或反射。但正确的答案是改变你的界面。 -
静态类不是正确答案???
-
为什么要避免使用 instanceof?如果您将所有武器存储在列表中但想在扩展类中调用方法,则需要在尝试投射之前检查类型。否则,将每个武器子类存储在其自己的列表中(这有其自身的缺点)。或者你对武器有一个通用的方法,比如“postAttackAction”,对于剑来说,它会从剑中抹去血,而对于其他武器,它会做其他事情。或者什么都没有。您只需要围绕哪些事情是“通用的”以及哪些事情是按类处理的做出设计决策。
-
另见:en.wikipedia.org/wiki/Chiburi“象征性地从剑刃上去除血迹的过程”:)
标签: java oop instanceof downcast