10-1 でボスインベーダーフォームを作る作業のうちの殆どは、普通のインベーダーのフォームを作る作業と同じです。このように、同じ作業を繰り返すのはいかにも面倒ですね。「一度作ったものはそのまま利用し、ただ新たに必要になった部分だけプログラミングする」という様にできないものでしょうか? 実は、まさにそれを実現してくれるのがオブジェクト指向プログラミングの最大の特徴なのです。
もちろん、(オブジェクト指向プログラミングに基づく) Delphi では、今までに作ったフォームの機能を別のフォームがそっくりそのまま受け継ぐことができます。さっそく確認してみましょう。
まずは、ボスインベーダーフォーム上から、普通のインベーダーフォームに既に存在しているコンポーネントを全て削除します。
すると、「乱数移動ボタン」だけが残ります。
さらに、boss_invader ユニットの中のイベントハンドラ (関数・手続き) のうち、普通のインベーダーが持っていたイベントハンドラ (関数・手続き) も消しましょう。すると、「乱数移動」ボタンに対応する ButtonRandomMoveClick だけが残ります。
最後に、先頭の uses 節と、その少し下の class(TForm) という部分を次のように書き換えます。
unit invader_boss; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Spin, Invader; type TFormInvaderBoss = class(TFormInvader) ButtonRandomMove: TButton; procedure ButtonRandomMoveClick(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var FormInvaderBoss: TFormInvaderBoss; implementation uses display, bullet; {$R *.DFM} // 「乱数移動」ボタン procedure TFormInvaderBoss.ButtonRandomMoveClick(Sender: TObject); begin SpinEditSpeed.Value := SpinEditSpeed.Value + Random(7) - 3; ButtonMoveClick(Sender); end; end.
書き換えが終わったら実行してみましょう。フォーム設計中は「乱数移動」ボタンしかなかったのに、実行すると他のコンポーネントが現れ、イベントハンドラ (手続き・関数) も殆ど削除してしまったのにフォームがちゃんと機能しています (“すごい!”と思いませんか!?)。
このようにあるフォームの機能を別のフォームが受け継ぐことを、継承といいます。そして、新しく加わる機能だけをプログラミングすることを差分プログラミングといいます。class(TFormInvader) と書くことによって、インベーダーフォームを継承しているのです。
FormInvader, FormInvaderBoss, FormBullet の3つのフォームの Visible プロパティを False にして実行してみてください。フォームが現れなくても正しく実行できますか?
インベーダーフォーム、またはボスインベーダーフォームを継承して、新しい種類の敵のフォームを作成してください。