頑張れデルファイ!!!#2 ユニットファイルの巻A!


 #1を読んだ人。ユニットファイルが部品の定義(=クラス)を納めたファイルだとわかったでしょうか?ここではユニットファイルの要素を頭から順に説明だ。
デルファイのトップページ  前のページ(#1)へ 

ソース バージョンによりません。ユニットソースの編集画面を見てください(F12)。下のようになっていると思います。バージョンによってusesの中身が多少変わりますが内容はほぼ同じはず。
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

end.
 これが、Form1(オブジェクト)の宣言です。
 プロジェクトファイルと微妙に違います。

 まずファイルの要素をみるためにインデント(字下げ)
されているところは無視します。純正のコードエディタが
段下げしてくれているので一つ階層の低い要素だと推測
できますね。−−はいそのとおりです。

 さてプロジェクトファイルと比べると...。
 同じこと。
 ・usesがある。
 ・ピリオド「.」で終わる。

 違うこと。
 ・interfaceという語がある。
 ・implementationという語がある。
 ・(今のところ)beginがない。
 ・typeとかvarがある。(implementationより上の行ですね。確認!)
なお、{$R *.dfm} は無視しましょう。コンパイラ指令です。

実験1
Unit1.pasの
var
  Form1: TForm1;
を切り取って

implementation
の下に移動してください。すなわち以下のように
ファイルを書き換えて実行(F9)してみて下さい。
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms, Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

implementation

var
  Form1: TForm1;

{$R *.dfm}

end.

[エラー] Project1.dpr(11): 未定義の識別子 : 'Form1'
とメッセージを残してコンパイルが通らなかったはずです。
理由をお教えします。interfaceの宣言の下からimplementation宣言の上までを
宣言部と言って、ここで定義したものは外部のファイルから利用可能です。
ですからForm1がProject1.dprファイルからは使えないので

  Application.CreateForm(TForm1, Form1);

がエラーで引っかかるのです。

因みにtype宣言はimplementationの下に持ってくる
ことすら許されてません。(一般にtypeを定義することは可能ですが、Form1は
Delphiが最初に立ち上げるFormとして登録しちゃってるので駄目です。)
interface部(宣言部)は他のファイルに見せる部分
inplementation部(実現部、実装部)はこのユニット中で処理すればよい部分
をそれぞれ指します。
ですから関数をユニットで定義してそれを外部ファイルでも使いたい
なら下のようにinterface部に引数と戻り値を書いて、
implementation部にbegin〜end;で終わる実装を書きます。
(この実装では、受け取った2つの整数a,bの積を結果として返します。)

interface
・・・・・・・・・・・
 function Foo(a,b:integer):integer;
・・・・・・・・・・・
inplementation
・・・・・・・・・・・
 function Foo(a,b:integer):integer;
  begin
    Result:=a*b;
  end;
・・・・・・・・・・・

もしこの関数はユニットの中でしか使わないというなら
interfaceになにも入れないで

interface
・・・・・・・・・・・
・・・・・・・・・・・
inplementation
・・・・・・・・・・・
 function Foo(a,b:integer):integer;
  begin
    Result:=a*b;
  end;
・・・・・・・・・・・
とします。

 定数、変数、クラス、関数・・・などが呼び出される範囲をスコープと
いいます。
 大規模な開発では、スコープを必要以上に広げないことが混乱を
少なくするのに重要です。
 必要のない部分を外に公開しないことをカプセル化といいます。
 オブジェクト指向に特有のことだとは思いませんが、オブジェクト指向
プログラミングの特徴の一つだといわれています。
スコープ
 左の図で、FooAは外部からも使える。 (外部ファイルのスコープに入っている。)
 一方、FooBは自分の属するユニット内でしか使えない。 (自ユニットにスコープが限定される。)

まとめ

(とりあえずの理解として、以下のようにまとめ)
・interface部は外部ファイルに公開する宣言部。
 実装はimplementationに書く。
・implementation部の実装しか書かれていないものは自ユニットでしか使えない。


スコープをむやみに広げないようにプログラムを書くことをカプセル化といいます。 (とりあえず。)

Navigation