オーバーライドキャッシングValueオーバーライド継承するときに使うと便利だったりする機能です。同じ名前のメソッドを呼んでいるのですが、違う動きをすることが出来ます。いわゆる、ポリモーフィズムを実現するのに非常に重要な機能です。ついでに、抽象クラスの紹介もしてしまいましょう。共通の機能だけど、違う動作をさせたい今回も、継承�@の例を元に説明していきます。関係を継承の機能を用いて記述しました。以下のコードは継承�@で載せたサンプルコードです。//キーコントロール}このコードは、戦闘機を表す「Combat」クラスには移動・レーザーを打つ・描画する機能を持たせ、派生した各クラスには別の名前で機体を制御するメソッドが実装されています。「Enemy」と「Player」クラスで別の動作をさせるためなのですが、これは、実質「AI()」と「KeyControl()」メソッドは機体をコントロールするという同じ機能を実装しているだけです。他にも、レーザーを打つという動作を「Enemy」と「Player」クラスで分けたいかもしれませんし、描画も別の動作をさせたいかもしれません。このような機能を実装できるのが今回紹介するオーバーライドです。オーバーライドは、派生元のメソッドの内容を書き換えてしまう機能です。簡単なオーバーライドまずは、上で紹介した例をコードに記述してみます。オーバーライドに関連するキーワードは以下の3つを知っておけば大丈夫でしょう。抽象メソッドであることを示す仮想やら、抽象やら何か嫌な言葉が出てきます。仮想メソッドと抽象メソッドの違いは後で紹介するとして、とりあえず「virtual」と「override」を使ってサンプルを作ってみます。書き換えられる可能性のあるメソッドに「virtual」キーワードを指定します。//戦闘機を操作する{//オーバーライド予定なので何もしない}}今回は、「Combat」クラスのうちで機体を操作する「Control()」と描画する「OnDraw()」の2つを後(派生先)で書き換える予定なので、この二つに「virtual」を指定します。次に、派生先でこの二つのメソッドをオーバーライドします。OnDraw(){//自機の描画処理}}これで、オーバーライドの完了です。これで、PlayerとEnemyオブジェクトは、同じ名前の「Control()」メソッドを呼び出しても別の動きをします。抽象クラス・抽象メソッドさて、ここで「Combat」クラスの役割を考えてみましょう。「Combat」クラスは「これを継承したクラスは全て戦闘機である」ことを表すクラスなのですが、はたしてゲーム中に戦闘機というものが存在する必要があるでしょうか?おそらく、敵味方良く分からないただの戦闘機というのはあまり必要はないでしょう。「Combat」クラスは実体化(インスタンスを作る)必要のないクラスであり、戦闘機という概念を表すためだけのクラスなのです。このようなクラスを抽象クラスと呼び(ホントかな)、クラスの前に「abstract」キーワードを追加します。抽象クラスはインスタンスを作ることが出来ません。new〜と出来ないのです。継承するためのクラスになります。抽象クラスの中だけで作れるメソッドがあります。それが、抽象メソッドです。抽象メソッドもメソッドの前に「abstract」キーワードを追加します。抽象メソッドは派生先で必ずオーバーライドする必要があり、メソッドの中身を書くことは出来ません。派生先のクラスでは必ず抽象メソッドをオーバーライドしなくてはいけません。説明だけしても分かりにくいので、Combatクラスを抽象クラス化してみます。//戦闘機を操作する}これで、Combatクラスは抽象クラスに、Control()とOnDraw()クラスは抽象メソッドになりました。抽象メソッドには中身の動作が書かれていませんね。抽象メソッドではこのようにメソッドの宣言だけしておけばいいのです。何がうれしい?オーバーライドさて、これでオーバーライドを実装し、クラス同士の関係やメソッドの名前を綺麗に記述できたわけです。名前を統一したいだけなら何もオーバーライドする必要はありません。継承�@の例のようにCombatクラスを作り、「AI()」と「KeyControl()」の名前を「Contorl()」としてしまえばいいだけです。オーバーライドをするのでしょうか?継承はクラスの関係性を表せます。「Enemy」も「Player」も「Combat」としての属性を持っており「Combat」の一種と見なせるわけです。このような扱い方をC#ではキャストを使って表現できます。Enemy();と、「Player」も「Enemy」も生成したインスタンスを「Combat」型の変数に代入して扱うことが出来ます。この機能を知っていてこそ、オーバーライドの真価ポリモーフィズムの効果が発揮されます。これを利用するとこんな動作が出来ます。Enemy();//Enemyで定義されたControl()が呼び出されるcombat.Control();一回目の「combat.Control();」では、combatがPlayer型のオブジェクトをさしているのでPlayerクラス内で定義されたControl()メソッドが呼び出され、2回目では、combatがEnemy型のオブジェクトをさしているのでEnemyクラス内で定義されたControl()メソッドを呼び出します。Control()をオーバーライドしていなかったらこのようなことは出来ません。これは、CombatクラスにControlメソッドがあることが保証されているからこと出来るのです。まとめ今回は、オーバーライド・抽象クラス・ポリモーフィズムとちょっとボリュームが多かったですね。ここら辺をうまく使ってプログラムすると、様々なときに便利になります。(投げやりな感想)次回は...ネタが思いつきませんね...とりあえず、配列、リスト、あとは〜C#2.0のジェネリックでも扱いましょうか。