10-2 普通のインベーダーから継承しよう

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) と書くことによって、インベーダーフォームを継承しているのです。

継承図

ここまでのプログラムをダウンロード(D)

【基礎課題 10-1】

FormInvader, FormInvaderBoss, FormBullet の3つのフォームの Visible プロパティを False にして実行してみてください。フォームが現れなくても正しく実行できますか?

【応用課題 10-1】

インベーダーフォーム、またはボスインベーダーフォームを継承して、新しい種類の敵のフォームを作成してください。