3
public abstract class Character
{
    protected Weapon weapon;

    public string Name;
    public int Health = 10;
    public int Strength;

    public Character()
    {
    }

    public void Attack()
    {
        weapon.useweapon();
    }
}

public class Warrior : Character
{
    public Warrior()
    {
        weapon = new Sword();
        Health = 10;
        Strength = 25;
    }

    public void SetWeapon(Weapon newweapon)
    {
        weapon = newweapon;
    }

}

public class Wizard : Character
{
    public Wizard()
    {
        weapon = new Spell();
        Health = 15;
        Strength = 10;
    }
}

ご覧のとおり、抽象Characterクラスと2つのCharacterサブクラスがあります。このプログラムでは、戦士だけが武器を変更できます。今、私はコード自体について議論するつもりはありません。私が知りたいのは、実装コードでなぜこれを使用するのかということです。

Character Zizo = new Warrior();
Character Hang = new Wizard();

それ以外の -

Warrior Zizo = new Warrior();
Wizard Hang = new Wizard();
Zizo.SetWeapon(new Axe()); //I can only use this method in this implementation

この2つの違いは何ですか?また、抽象クラスでオブジェクトを宣言することでどのようなメリットがありますか?

4

6 に答える 6

4

クライアントコードは、最小限必要なインターフェイスまたは抽象クラス定義を使用する必要があります。これは主に、コードをより緩く結合するために行います。あなたの例では、呼び出し元のコードが必要なだけで、Attack()それがどのように実行、実装されているか、または特定のタイプ(たとえばWarriorWizardなど)が攻撃を行っているかどうかに関係がない場合は、abstract Characterクラスを使用する必要があります。

特定の実装または具象クラスの知識が必然的に必要な場合は、明示的に使用することが適切です。

于 2012-04-25T18:28:32.920 に答える
3

Characterあなたが得るものは、それが何であるかに関係なく、あらゆる文字タイプで公開されているタイプメンバーと相互作用できるコードを書く能力です。

元:

public void AttackAndHeal(Character character)
{
    character.Attack();
    character.Health++;
}

Warrior zizo = new Warrior();
Wizard hang = new Wizard();

AttackAndHeal(zizo);
AttackAndHeal(hang);
于 2012-04-25T18:28:25.433 に答える
1

あなたがいつもあなたがそれらをそのように使うことを知っているならば、必要はありません。しかし、多くの場合、キャラクターのタイプを抽象化し、すべてのキャラクターによって実装されるアクションのみを実行したい場合があります。

誰かが画面の真ん中にH爆弾を落としたとしましょう。キャラクターがウィザードであるかWarriors()であるかは関係ありません。したがって、Killまたは任意のメソッドを呼び出すだけで済みます。

于 2012-04-25T18:28:43.463 に答える
1

クラスの任意のメンバーの一般的なコレクションを作成Warriorして再利用できますWizardCharacter

var characters = new List<Character>();
characters.Add(new Warrior());
characters.Add(new Wizard());
foreach (var c in characters)
{
    //use members exposed by c
}
于 2012-04-25T18:28:59.493 に答える
0

基本クラスと子クラスに同じ名前の通常のメソッド(つまり、オーバーライドされていない)がある場合、オブジェクトの変数を基本クラスとして入力すると、メソッドが呼び出されたときに基本クラスのメソッドが選択されます。あなたがその振る舞いを探しているなら、それはそれをキャラクターとしてタイプする理由かもしれません。戦士をリストに追加するか、パラメーターとして文字を必要とするメソッドに渡すと、自動的に文字にキャストされるため(私は思う)、戦士を文字として入力すると、コードのエラーが発生しにくくなる可能性があります。リストに追加したり、文字タイプを必要とするその他のことをしたりします。

于 2012-10-23T00:42:36.660 に答える
0

Zizoとして宣言することにより、任意のタイプのオブジェクトをにCharacter割り当てることができるようになりました。残念ながら、これにより、に対して明示的に宣言されたプロパティと関数のみを呼び出すように制限されます。に固有の何かを呼び出すには、最初にそれをキャストする必要があります。CharacterZizoCharacterZizoWarrior

于 2012-04-25T18:29:31.683 に答える