我已经在线阅读了n
次,除非我们使用它来实现类的instanceof
方法,否则我应该总是尽量避免使用.equals()
运算符。< / p>
据说,只要有可能,我们应该尝试实现多态,而不是使用instanceof
来确定对象的类型,以决定以下行为。
例如:http://www.javapractices.com/topic/TopicAction.do?Id=31
然而,在这个特定情况下,我在super&amp; amp;中没有任何可用的方法。子类(除了toString,equals,accessor和mutator方法)。使用instanceof
是否有效?
class Warrior
{
int damage;
int defense;
Item handSlot;
public Warrior(){
damage = 0;
defense = 0;
handSlot = null;
}
private void equipHand(Item item)
{
//Determine class of object to decide further actions
if (item instanceof Weapon){
this.handSlot= item;
this.damage += ((Weapon)item).getDamage();
}
else if (item instanceof Shield){
this.handSlot = item;
this.defense += ((Shield)item).getProtection();
}
}
}
class Item
{
private String name;
public Item(String name)
{
this.name = name;
}
}
class Shield extends Item
{
private int protection;
public Shield(String name, int protection){
super(name);
this.protection = protection;
}
public int getProtection(){
return protection;
}
}
class Weapon extends Item
{
private int damage;
public Weapon(String name, int damage){
super(name);
this.damage = damage;
}
public int getDamage(){
return damage;
}
}
请注意,如果Weapon, Item & Shield class
有重载方法(例如:equip()
),我可以简单地使用多态。但在这种情况下,装备方法在另一个类中。 在此特定情况下,是否可以使用 instanceof
运营商?或者它仍然是一个糟糕的设计?
答案 0 :(得分:3)
您的设计的替代方法是将equipHand
方法从Warrior
移至Item
(也可以根据此更改它):
/* in Item */
public abstract void giveToWarrior(Warrior w);
/* in Weapon */
@Override
public void giveToWarrior(Warrior w) {
w.setHandSlot(this);
w.increaseDamageBy(getDamage());
}
/* in Shield */
@Override
public void giveToWarrior(Warrior w) {
w.setHandSlot(this);
w.increaseProtectionBy(getProtection());
}
(我已经使用了Warrior
中不存在的一些方法,但是它们的功能应该是不言自明的。进行指示的更改需要实现这些方法。)
此设计解决了当前设计的主要问题,即添加新的Item
子类会变得很麻烦,因为这样做也需要更新equipHand
。
答案 1 :(得分:1)
如您所知Shield
和Weapon
都延伸Item
。因此,最好使用其功能覆盖每个类中的equipHand
方法。使用item
实例的直接访问方法,而不是使用instance of
进行检查。
上述实现的问题,它将为每个类重载额外的方法。
为避免额外的重载方法,请根据要求创建不同的接口。 IWeapon , iShield 就像明智一样。在提及界面中定义特定方法。为了更清楚地阅读Head First Design Pattern
书的第一章,这将对你有所帮助。