2013-10-19 60 views
1

我正在与英雄有一个库存充满了对象的小游戏。我的对象类继承武器类和护甲类的继承关系

public enum Objects_type 
{ 
    WEAPON, 
    ARMOR 
} 

public abstract class Objects_class 
{ 
    protected String name; 
    protected Objects_type type; 

    public Objects_class(String name, Objects_type type) 
    { 
     this.name = name; 
     this.type = type; 
    } 
} 

public abstract class Armor extends Objects_class{ 

    int life = 0; 
    int res_fire = 0; 

    public Armor(String name, int largeur, int hauteur) { 
     super(name, Objects_type.ARMOR); 
    } 
} 

public abstract class Weapon extends Objects_class 
{ 
    protected int dmg_fire = 0; 

    public Weapon(String name) { 
     super(name, Objects_type.WEAPON); 
    } 
} 

public class StickOfJoy extends Weapon{ 

    public StickOfJoy() { 
     super("Stick of Joy"); 
     dmg_fire = 2; 
    } 
} 

public class ArmorOfPity extends Armor{ 
    public ArmorOfPity() 
    { 
     super("Armor of Pity"); 
     life = 30; 
    } 
} 

然后,我有这样的功能:

Hero.getObject (Objects_class obj) 
{ 
    if (obj.getType == Objects_type.WEAPON) 
    .... 
} 

我希望能够考虑Objects_class OBJ作为武器,但当然这是不可能的(铸造母亲的孩子),所以它让我觉得我的继承结构很糟糕。

我该怎么做?

+3

请标签的编程语言和/或框架您使用的问题。不要让我们通过语法来推断。 –

+1

我的建议取决于你在if(obj.getType == ...)中做什么。 – arynaq

+0

@JonathonReinhart完成了,对不起。 – IggY

回答

1

大卫康拉德有一些好点我建议你通读一下,我不会在这里重复,但这里是我将如何做到这一点。

假设你有一个角色在你的游戏世界中捡取物品,可以有许多不同的项目,一些行为上彼此如此不同,他们保证创建一个新的子类(例如拾起靴子vs捡起翅膀)。

一旦你拿起一件物品,你可以选择让英雄尝试并看看拾取了什么样的物品(instanceof,枚举等等),或者你可以让物品找出它应该去的地方。

这里是一个简单的例子,玩家只有两个库存插槽,武器和盔甲。注意简单地添加一个新物品(如健康药水或超级新闻专用武器)到混音中是多么容易,而无需更改播放器中的任何内容或进行投射。

public abstract class Item { 
    private int ID; 
    private static int IDCounter; 
    private String name; 

    public Item(String name) { 
     this.name = name; 
     this.ID = IDCounter; 
     IDCounter++; 
    } 

    public int getID() { 
     return ID; 
    } 

    public String getName() { 
     return name; 
    } 

    public abstract void attachToPlayer(Player player); 
} 

public class Armor extends Item { 
    private int life; 
    private int res_fire; 

    public Armor(String name) { 
     super(name); 
    } 

    @Override 
    public void attachToPlayer(Player player) { 
     // Only equip if upgrade 
     if (player.getArmor().res_fire > this.res_fire) 
     player.setArmor(this); 

    } 

} 


public class Weapon extends Item { 
    private int dmg_fire; 

    public Weapon(String name) { 
     super(name); 
    } 

    // ...stuff 

    @Override 
    public void attachToPlayer(Player player) { 
     // Only equip this if upgrade? You decide the logic 
     if(player.getWeapon().dmg_fire>this.dmg_fire) 
      player.setWeapon(this); 
    } 

} 

public class SuperSpecialWeapon extends Weapon { 
    private float bonusHealthModifier = 1.0f; 
    public SuperSpecialWeapon(String name) { 
     super(name); 
    } 

    @Override 
    public void attachToPlayer(Player player) { 
     // This bonus adds +100%HP bonus to the player! 
     int hp = (int) ((1 + bonusHealthModifier) * player.getHealth()); 
     player.setHealth(hp); 
     player.setWeapon(this); 
    } 

} 

public class Potion extends Item { 
    private int health = 100; 

    public Potion() { 
     super("HealthPotion"); 
    } 

    @Override 
    public void attachToPlayer(Player player) { 
     // If the player has room for one more potion, pick this up 
     Potion[] potions = player.getHealthPotions(); 
     for (int i = 0; i < potions.length; i++) { 
      if(potions[i]==null){ 
       potions[i] = this; 
       break; 
      } 
     } 
    } 

    // ..other stuff 
} 

最后玩家

public class Player { 
    private Armor armor; 
    private Weapon weapon; 
    private String name; 
    private Potion[] healthPotions = new Potion[10]; 
    private int health; 

    public Player(String name) { 
     this.name = name; 
    } 

    public Armor getArmor() { 
     return armor; 
    } 

    public Weapon getWeapon() { 
     return weapon; 
    } 

    public void setWeapon(Weapon weapon) { 
     this.weapon = weapon; 
    } 

    public void setArmor(Armor armor) { 
     this.armor = armor; 
    } 

    public void setHealth(int health) { 
     this.health = health; 
    } 

    public int getHealth() { 
     return health; 
    } 

    public Potion[] getHealthPotions() { 
     return healthPotions; 
    } 

} 
+0

很好的答案,谢谢:)) – IggY

1

由于Java中的对象知道它们是什么类型,因此不需要Objects_type,,并且可以使用instanceof运算符测试它们的类型。你说你不能投“一个母亲给它的孩子”,但是可以将一个对象向下注入一个孩子类型。一般来说,它可能会抛出一个ClassCastException,,但是如果你已经用instanceof,第一次测试它,那将不会发生。

public class Objects_class { 
    protected String name; 

    public Objects_class(String name) { 
     this.name = name; 
    } 
} 

public class Armor extends Objects_class { 
    int life = 0; 
    int res_fire = 0; 

    public Armor(String name, int largeur, int hauteur) { 
     super(name); 
    } 
} 

public class Weapon extends Objects_class { 
    protected int dmg_fire = 0; 

    public Weapon(String name) { 
     super(name); 
    } 
} 

public class Hero { 
    public void getObject(Objects_class obj) { 
     if (obj instanceof Weapon) { 
      Weapon weapon = (Weapon) obj; 
      wield(weapon); 
     } 
     if (obj instanceof Armor) { 
      Armor armor = (Armor) obj; 
      wear(armor); 
     } 
    } 
} 

我已删除从类abstract修改,因为没有必要的,但也许你希望它确保这些基类永远不会实例。此外,我会将Objects_class的名称更改为Item之类的名称,因为Object和class这两个词具有特殊含义,可能会导致混淆。我也会将英雄的getObject方法重新命名为pickUpItem,因为它不是Java的意义上的吸气剂。

+0

伟大的答案,谢谢:) – IggY