我试图找到绕过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
}
答案 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
运营商。
关于介绍设计模式的注意事项
引入设计模式时应该小心。人们养成了直接跳到复杂模式来解决问题的坏习惯,当真正的东西变得更简单并且(在我看来)更优雅的时候。