Unit Friend
Delphi の可視性
Object Pascal は、他の言語同様にクラスメンバに対する可視性を制御できます。
一般的な可視性は下記の通りです。
指令 | アクセス範囲 |
---|---|
private | 宣言されたクラス |
protected | 宣言されたクラス, 継承先のクラス |
public | 誰でも |
published | 誰でも(RTTI が生成される) |
※一般的では無い可視性として automated があります
本当に?
本当のことを言うとちょっと違います。
実は private と protected は更に「同一 Unit 内」からもアクセスできるのです。
Embarcadero Developer Network の記事「Delphi 7以降の言語およびコンパイラの新機能」には
privateキーワードは実際には同一ユニット内のクラス間に「フレンド」な関係を作成します
とあります。
例えば
type
TFoo = class
private
FBar: String;
public
constructor Create; reintroduce;
end;
TBar = class
public
constructor Create(const iFoo: TFoo); reintroduce;
end;
{ TFoo }
constructor TFoo.Create;
begin
FBar := 'I am TFoo.'
end;
{ TBar }
constructor TBar.Create(const iFoo: TFoo);
begin
// TFoo.FBar は private なのにアクセスできる
iFoo.FBar := 'You are TBar';
end;
上記のようにアクセスできます。
この機能を勝手に Unit Friend と呼んでいます。
strict 指令
Unit friend は親子関係があったり関係性の深いクラスを作るときに利用されるテクニックですが、それをさせたくない場合があります。
それを制御するために strict 指令というものがあります。
指令 | アクセス範囲 |
---|---|
strict private | 宣言されたクラス |
strict protected | 宣言されたクラス 継承先のクラス |
このように strict を付けると、Unit friend の機能は無くなり、厳密にアクセス範囲が決定されます。
まとめ
可視性についてまとめると
指令 | アクセス範囲 |
---|---|
strict private | 宣言されたクラス |
private | 宣言されたクラスと同一ユニット |
strict protected | 宣言されたクラスと継承先のクラス |
protected | 宣言されたクラスと継承先のクラスと同一ユニット |
public | 誰でも |
published | 誰でも(RTTI が生成される) |
となります。