避免 instanceof Java

Avoiding instanceof Java

我正在尝试找到一种绕过 instanceof 使用的方法。我创建了一个 class 物品,它有多个子 class 元素,例如 WeaponItem 和 BodyItem。现在我想做一个调用,比如 equip(Item),它应该自己确定它应该调用哪个重载函数,比如 equip(BodyItem)。

在这种情况下有没有办法绕过 instanceof 的使用?您会推荐什么?我听说在大多数情况下使用 instanceof 是不好的做法,因此我想知道替代方案是什么。

代码:

inv.equip(it); // inv = inventory object, it = Item

物品栏中装备功能的示例class我最想要它的方式

public void equip(HelmItem it) 
{
    if (it != this.getHelm())
    {
        this.setHelm(it);
    }
}

我之前是怎样的:

public void equip(Item it)
{
    if (it instanceof WeaponItem)
    {
        if (it != this.getWeapon())
        {
            this.setWeapon((WeaponItem) it);
        } 
    } etc for all subclasses of item
}

为什么不把方法放在Item具体的class里面,它自己就可以装备了?这有点违反直觉,但它会解决你的问题。

public class SomeConcreteItem extends Item {
    public void equip(Body body) {
        // Just an example.
        body.getSections().get(0).equip(this);
    }
}

这样一来,具体的实现就知道如何装备自己,而使用它的 classes 并不关心。你可以通过 Item superclass 引用它,只要 Item superclass 有一个抽象方法 public void equip(Body body);,那么你永远不需要了解具体实现,因此不需要 instanceof 运算符。

介绍设计模式的注意事项

你应该小心引入设计模式。人们有一个坏习惯,即直接跳到复杂的模式来解决问题,而实际上更简单(在我看来)更优雅的东西是可用的。

的确,这可以通过访问者模式来解决。

但是,它不一定是成熟的访问者,而是它的简化变体。您可以将库存传递给物品,让物品为所欲为:

abstract class Item {
    public abstract void equip(Inventory inv);
}

class HelmItem extends Item {
    @Override
    public void equip(Inventory inv) {
        inv.setHelm(this);
    }
}

class WeaponItem extends Item {
    @Override
    public void equip(Inventory inv) {
        inv.setWeapon(this);
    }
}

那你就可以打电话了:

it.equip(inv)

没有 instanceof 运算符。