フィールド(Delphi)
クラスとオブジェクト:インデックス への移動
このトピックでは、クラスのデータ フィールド宣言の構文について説明します。
フィールドの概要
フィールドは、オブジェクトに属する変数のようなものです。フィールドは、クラス型など、どのような型でもかまいません。つまり、フィールドにはオブジェクト参照を格納することができます。フィールドの可視性は通常、private です。
クラスのフィールド メンバを定義するには、変数の場合と同じようにフィールドを宣言するだけです。たとえば、以下の例では、System.TObject から継承したメソッド以外には Int という整数型フィールドしかメンバがない TNumber というクラスを宣言しています。
type
TNumber = class
var
Int: Integer;
end;
var キーワードは省略可能です。ただし、このキーワードを使用しない場合は、すべてのフィールド宣言をプロパティまたはメソッドの宣言より前に記述する必要があります。プロパティまたはメソッドの宣言の後では、var を使用すれば、フィールド宣言を追加できます。
フィールドは静的にバインドされます。つまり、フィールドへの参照はコンパイル時に解決されます。このことを具体的に確認するために、以下のコードについて考えます。
type
TAncestor = class
Value: Integer;
end;
TDescendant = class(TAncestor)
Value: string; // hides the inherited Value field
end;
var
MyObject: TAncestor;
begin
MyObject := TDescendant.Create;
MyObject.Value := 'Hello!' // error
(MyObject as TDescendant).Value := 'Hello!' // works!
end;
MyObject には TDescendant のインスタンスが格納されますが、このオブジェクトは TAncestor として宣言されています。したがって、コンパイラは MyObject.Value を TAncestor で宣言されている(整数型)フィールドへの参照と解釈します。ただし、どちらのフィールドも TDescendant オブジェクトに存在します。継承した方の Value は新しいフィールドで隠蔽されますが、型キャストを通じてアクセスできます。
定数と型付き定数の宣言は、グローバル スコープのクラスと非無名レコードに記述できます。定数と型付き定数はどちらも、ネストした型の定義にも記述できます。定数と型付き定数は、クラスが手続きに対してローカルに定義されている場合に、そのクラス定義内にのみ記述できます。つまり、手続き内に定義されるレコードの中には記述できません。
クラス フィールド
クラス フィールドは、(上記で説明した通常の "インスタンス フィールド" とは異なり)オブジェクト参照なしでアクセスできる、クラス内のデータ フィールドです。クラス フィールドに格納されるデータは、クラスのすべてのインスタンスで共有され、クラスまたはクラスのインスタンスを表す変数を参照することでアクセスできます。
class var ブロック宣言を使用することで、クラス宣言内にクラス フィールドのブロックを導入できます。class var の後に宣言されたフィールドはどれも、静的な格納属性を持ちます。class var ブロックは、次のいずれかで終了します。
- 別の class var 宣言または var 宣言
- 手続きまたは関数(メソッド)の宣言(クラス手続きとクラス関数を含む)
- プロパティ宣言(クラス プロパティを含む)
- コンストラクタまたはデストラクタの宣言
- 可視性指定子(public、private、protected、published、strict private、strict protected)
以下に例を示します。
type
TMyClass = class
public
class var // Introduce a block of class static fields.
Red: Integer;
Green: Integer;
Blue: Integer;
var // Ends the class var block.
InstanceField: Integer;
end;
クラス フィールド Red、Green、Blue には、以下のコードでアクセスできます。
TMyClass.Red := 1;
TMyClass.Green := 2;
TMyClass.Blue := 3;
また、クラス フィールドは、クラスのインスタンスを通じてアクセスすることもできます。以下の宣言があるとします。
var
myObject: TMyClass;
以下のコードは、上記の Red、Green、Blue への代入と同じ効果があります。
myObject.Red := 1;
myObject.Green := 2;
myObject.Blue := 3;