避免Java的实例

时间:2015-06-20 11:45:38

标签: java instanceof

我试图找到绕过instanceof使用的方法。我创建了一个类Item,它有多个子类,如WeaponItem和BodyItem。现在我想做一个如装备(Item)的调用,它应该自己确定它应该调用哪个重载函数,例如equip(BodyItem)。

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

代码:

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

库存类中装备功能的一个例子我最喜欢它

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
}

2 个答案:

答案 0 :(得分:3)

事实上,这可以通过访客模式来解决。

但是,它不一定是一个成熟的访问者,而是一个简化的变体。您可以将库存传递给该项目,让该项目随意执行:

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运算符。

答案 1 :(得分:2)

为什么不将方法放在block具体类中,它可以装备自己?这有点反直觉,但它可以解决你的问题。

.phone {
  font-size: 10px;
  background: #333 none repeat scroll 0% 0%;
  color: #262626;
  border-radius: 3px;
  padding: 30px 23px;
}
.dl-horizontal dt {
  line-height: 15px;
  margin-top: 3px;
  padding-left: 10px;
}
.dl-horizontal {
  color: #000;
  font-size: 11px;
  display: inline-block;
}
.col-md-4 i {
  margin: 0px 0px 0px 10px !important;
}
.col-md-12 i {
  margin: 0px 12px 0px 15px;
}

这样,具体实现知道如何装备自己,并且使用它的类不关心。您可以通过<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" /> <div class="ef-widget-inner"> <div class="col-md-12 col-lg-12 nopadding"> <i class="fa fa-phone phone"></i> <dl class="dl-horizontal"> <dt>Title 1.................</dt> <dd><a href="contact.php"><span><i>28311</i></span></a> </dd> <dt>Title 2</dt> <dd><a href="contact.php"><span><i>28312</i></span></a> </dd> <dt>Title 3</dt> <dd><a href="contact.php"><span><i>28314</i></span></a> </dd> </dl> </div> </div>超类引用它并且假设Item超类具有抽象方法public class SomeConcreteItem extends Item { public void equip(Body body) { // Just an example. body.getSections().get(0).equip(this); } } ,那么您不需要知道具体实现,因此,不需要需要Item运营商。

关于介绍设计模式的注意事项

引入设计模式时应该小心。人们养成了直接跳到复杂模式来解决问题的坏习惯,当真正的东西变得更简单并且(在我看来)更优雅的时候。