避免 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
运算符。
我正在尝试找到一种绕过 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
运算符。