クラス型変数の宣言と実際にオブジェクトが生成されることとは別の事だという事を理解してください。クラス型の変数を宣言しただけでは、オブジェクトは生成されてはいないのです。
type TBook = class(TObject) private FNumber: Integer; public procedure ShowNumber; end; ........................ procedure TBook.ShowNumber; begin ShowMessage(IntToStr(FNumber)); end; procedure TForm1.Button1Click(Sender: TObject); var Book: TBook; // クラス型変数を宣言 begin Book.ShowName; // まちがい!オブジェクトは、生成されていません。 Book := TBook.Create; // オブジェクトの生成 Book.ShowNumber; // メソッドにアクセス Book.Free; // 使い終わったら破棄 end;
クラス型変数( ここでは Book ) を宣言しただけでは、オブジェクトはまだ生成されていません。つまり、この宣言はBook が「 TBook 型のオブジェクトへの参照( この参照については、後でもう少し詳しく解説します。) を保持できる変数である」という事以外の意味を持ちません。ですからコンストラクタで「オブジェクトの生成」、そしてオブジェクトが不要になったらデストラクタで「オブジェクトの破棄」を必ず行ってください。
次に、コンストラクタでの初期化ですが、TBook 型のオブジェクトを生成した後、メソッドShowNumber を呼び出しています。この ShowmNuber では、フィールド FNumber にアクセスしています。
さて、ShowNumber では、なんと表示されるでしょうか?もし、ButtonClick イベントハンドラのなかで、局所変数 i: Integer を宣言した場合には、使用する前に必ず初期化をしなければなりませんでした。今回の FNumber のケースも初期化を行わなければならないのですが、明示的に初期化をしない場合でも FNumber は、0 に初期化されています。実際、オブジェクトを生成する時にコンストラクタがフィールドを初期化してくれています。もちろん、例えばオブジェクトを生成した時に FNumber を 100 に初期化したい場合は、それをコンストラクタに書いてやれば任意の値に初期化することが出来ます。以下の例を見てください。
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; TBook = class(TObject) private FNumber: Integer; public constructor Create; // コンストラクタ procedure ShowNumber; end; var Form1: TForm1; implementation {$R *.dfm} { TBook } constructor TBook.Create; begin FNumber := 100; // 100 で初期化 end; procedure TBook.ShowNumber; begin ShowMessage(IntToStr(FNumber)); end; procedure TForm1.Button1Click(Sender: TObject); var Book: TBook; begin Book := TBook.Create; Book.ShowNumber; Book.Free; end;
あくまで、明示的に初期化をしない場合にはコンストラクタが自動的に初期化 (本当は、0 に初期化されてから、FNumber := 100; が実行されています) をしてくれているということです。
ここでグローバル変数、局所変数についても復習してみましょう。
var Tmp: Integer = 100; Number: Integer; procedure TForm1.Button1Click(Sender: TObject); var Time: Integer; begin Time := 20; // 必ず使う前に初期化をします ShowMessage(IntToStr(Time)); ShowMessage(IntToStr(Tmp)); // OK! ShowMessage(IntToStr(Number)); // OK! end;
明示的に初期化されていないグローバル変数も 0 に初期化されています。