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 を武器と見なしたいのですが、もちろん不可能です (母を子にキャストする) ので、継承構造が悪いと思います。

私は何をすべきでしたか?

4

2 に答える 2

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を次のように変更します。また、Java の意味での getter ではないため、ItemHero のgetObjectメソッドの名前を次のように変更します。pickUpItem

于 2013-10-19T18:47:56.907 に答える
1

David Conrad にはいくつかの良い点があります。ここでは繰り返しませんが、ここではその方法を説明します。

ゲームの世界を歩き回ってアイテムを拾っているキャラクターがいるとします。多くの異なるアイテムが存在する可能性があり、いくつかのアイテムは互いに動作が非常に異なるため、新しいサブクラスを作成する必要があります (ブーツを拾う vs 翼を拾うなど)。 .

アイテムを拾ったら、主人公にどの種類のアイテムが拾われたか (instanceof、enum など) を試して見てもらうか、アイテムがどこに行くべきかをアイテムに理解させることができます。

これは、プレイヤーが武器と防具の 2 つのインベントリ スロットしか持たない単純化された例です。プレーヤーで何も変更したり、キャストを実行したりすることなく、新しいアイテム (ヘルス ポーションや超大型の新しい特殊武器など) をミックスに簡単に追加できることに注目してください。

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;
    }

}
于 2013-10-20T00:48:13.643 に答える