2012-04-25 11 views
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サブクラスがあります。このプログラムでは、戦士だけが武器を変更することができます。ある何オブジェクトを、それ自身のクラスの代わりに継承した抽象クラスで宣言する理由

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

-

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

の代わりに:さて、私はコード自体を議論するために探していないよ、私はこれを使用する理由、私が知りたいことは、私の実装コードでは、両者の違いと、抽象クラスでオブジェクトを宣言することで得られるメリットは何ですか?

+1

OOの概念をしっかりと把握していないような音がします。そのテーマに関する本を読むのに少し時間を費やす価値があるかもしれません。 – R0MANARMY

+0

なぜそう思うか教えてください。 – Zizo47

答えて

4

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

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

+0

さらに良いIAttackインターフェイスは、 – MikeSW

3

公開されて公開されているCharacterタイプのメンバーと対話できるコードを、文字タイプに関係なく任意の文字タイプに書き込むことができます。

例:

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

AttackAndHeal(zizo); 
AttackAndHeal(hang); 
+0

継承によりこれが可能です。私が知りたいのは、なぜCharacterとして宣言しているかです。 – Zizo47

+0

実際には継承ではなく、多形性です。継承では、単に親から型を派生させることができます。ポリモーフィズムは、型を別の型(親または実装されたインタフェース)として扱うことを可能にするものです。つまり、具体的な型を直接インスタンス化してローカル変数に代入する場合、親クラスを使用する利点はありません。メソッド、複合型、ファクトリメソッド、依存性注入、ジェネリックなどで作業している場合は、親タイプを使用することで多くの利点があります。 –

1

あなたはいつもあなたがそのようにそれらを使用することを知っているなら、必要はありません。しかし、多くの場合、文字の種類を抽象化して、すべての文字によって暗黙のうちに実行されるアクションのみを実行したいとします。

誰かが画面の中央にH爆弾を落としたとしましょう。キャラクターがWizardsかWarriorsのいずれかであるかどうかは気にしないでしょう。彼らはすべて死に絶えるでしょうから、あなたはKillやその他の方法を呼び出すだけでよいのです。あなたがWarriorWizardの一般的なコレクションを持っているとCharacterとしてZizo宣言することによりCharacterクラス

var characters = new List<Character>(); 
characters.Add(new Warrior()); 
characters.Add(new Wizard()); 
foreach (var c in characters) 
{ 
    //use members exposed by c 
} 
+4

でなければなりません。あなたの投稿に署名する必要はありません。私はあなたのためにそれを編集しました。 – Yuck

1

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

+0

私が言ったように、私はコードの改善を探しているわけではなく、単なる説明です。とにかくありがとう... – Zizo47

+2

@ Zizo47彼は改善について話していたとは思いません。あなたのオブジェクトを抽象タイプとして扱うときの例です。あなたがそれらのコレクションでいくつかの操作を実行する場合。 – R0MANARMY

0

の任意のメンバーを再利用することができ

0

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

関連する問題