このドキュメントでは、クラスを定義および使用してアプリケーションを開発する方法について説明します。
以下のトピックについて説明します。
Windows プラットフォームでのクラスの開発
Windows プラットフォームでは、Natural クラスを開発するためのツールとして、Natural からクラスビルダが提供されます。クラスビルダは、構造化された階層順に Natural クラスを表示し、ユーザーがクラスとそのコンポーネントを効率的に管理できるようにします。クラスビルダを使用すると、この後で説明する構文要素に関する知識はまったく必要ないか、または基礎知識だけで済みます。
SPoD を使用したクラスの作成
メインフレーム、UNIX、または OpenVMS の一部またはすべてのリモート開発サーバーが含まれる Natural Single Point of Development(SPoD)環境では、Natural スタジオのフロントエンドで使用可能なクラスビルダを使用して、メインフレーム、UNIX、または
OpenVMS プラットフォーム上でクラスを開発できます。この場合、この後で説明する構文要素に関する知識はまったく必要ないか、または基礎知識だけで済みます。
メインフレーム、UNIX、または OpenVMS プラットフォームでのクラスの開発
SPoD を使用しない場合は、Natural プログラムエディタを使ってこれらのプラットフォームのクラスを開発することができます。この場合は、この後で説明するクラス定義の構文の知識が必要です。
クラスを定義するときは、Natural クラスモジュールを作成する必要があります。この中で DEFINE
CLASS ステートメントを作成します。DEFINE CLASS ステートメントを使用して、外部的に使用可能な名前をクラスに割り当て、そのインターフェイス、メソッドおよびプロパティを定義します。クラスのインスタンスのレイアウトを記述するオブジェクトデータエリアをクラスに割り当てることもできます。
このセクションでは、次のトピックについて説明します。
Natural クラスモジュールを作成するには
CREATE
OBJECT ステートメントを使用して、クラスタイプの Natural オブジェクトを作成します。
DEFINE
CLASS ステートメントは、クラスの名前、クラスがサポートするインターフェイス、およびそのオブジェクトの構造を定義します。
クラスを指定するには
DEFINE
CLASS ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
クラスの各インターフェイスは、クラス定義内部の INTERFACE ステートメントで指定されます。INTERFACE ステートメントは、インターフェイスの名前と多数のプロパティおよびメソッドを指定します。COM クラスとして登録されるクラスについては、インターフェイスのグローバルユニーク ID も指定されます。
クラスには 1 つ以上のインターフェイスを定義できます。インターフェイスごとに 1 つの INTERFACE ステートメントがクラス定義に指定されます。各 INTERFACE ステートメントには 1 つ以上の PROPERTY 節および METHOD 節が含まれます。通常、1 つのインターフェイスに含まれるプロパティとメソッドは、技術またはビジネスのいずれかの観点から関連付けられます。
PROPERTY 節はプロパティの名前を定義し、オブジェクトデータエリアからプロパティに変数を割り当てます。この変数を使用して、プロパティの値を保存します。
METHOD 節はメソッドの名前を定義し、メソッドにサブプログラムを割り当てます。このサブプログラムを使用して、メソッドを実装します。
インターフェイスを定義するには
INTERFACE ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
PROPERTY ステートメントは、複数のクラスが同じインターフェイスを異なる方法で実装するときにのみ使用されます。この場合、クラスは同じインターフェイス定義を共有し、Natural コピーコードからインクルードします。次に PROPERTY ステートメントを使用して、インターフェイス定義の外でオブジェクトデータエリアからプロパティに変数を割り当てます。INTERFACE ステートメントの PROPERTY 節と同様に、PROPERTY ステートメントはプロパティの名前を定義し、オブジェクトデータエリアからプロパティに変数を割り当てます。この変数を使用して、プロパティの値を保存します。
オブジェクトデータ変数をプロパティに割り当てるには
PROPERTY ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
METHOD ステートメントは、複数のクラスが同じインターフェイスを異なる方法で実装するときにのみ使用されます。この場合、クラスは同じインターフェイス定義を共有し、Natural コピーコードからインクルードします。METHOD ステートメントは、インターフェイス定義の外でサブプログラムをメソッドに割り当てるために使用されます。INTERFACE ステートメントの METHOD 節と同様に、METHOD ステートメントはメソッドの名前を定義し、サブプログラムをメソッドに割り当てます。このサブプログラムを使用して、メソッドを実装します。
サブプログラムをメソッドに割り当てるには
METHOD ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
メソッドは次のような一般形式の Natural サブプログラムとして実装されます。
DEFINE DATA statement * * Implementation code of the method * END
DEFINE
DATA ステートメントの詳細については、『ステートメント』ドキュメントを参照してください。
DEFINE DATA ステートメントのすべての節はオプションです。
データの整合性を確保するために、インラインデータ定義ではなくデータエリアを使うことをお勧めします。
PARAMETER 節を指定すると、メソッドにパラメータや戻り値を指定することができます。
パラメータデータエリアの BY
VALUE とマークされたパラメータは、メソッドの入力パラメータです。
BY VALUE とマークされていないパラメータは、"参照によって"渡される入力/出力パラメータです。これがデフォルトです。
BY VALUE
RESULT とマークされている最初のパラメータが、メソッドの戻り値として返されます。複数のパラメータがこのようにマークされている場合は、その他のパラメータは入力/出力パラメータとして扱われます。
OPTIONAL とマークされたパラメータは、メソッドが呼び出される場合は指定する必要はありません。SEND
METHOD ステートメントで nX 表記を使用することにより、これらを未指定にしておくことができます。
メソッドサブプログラムが、クラス定義内の対応する METHOD ステートメントに指定されたものとまったく同じパラメータを受け入れるようにするには、インラインデータ定義ではなくパラメータデータエリアを使用します。対応する METHOD ステートメント内のものと同じパラメータデータエリアを使用します。
メソッドサブプログラムでオブジェクトデータ構造にアクセスするために、OBJECT 節を指定できます。メソッドサブプログラムがオブジェクトデータに正しくアクセスできるようにするには、インラインデータ定義ではなくローカルデータエリアを使用します。DEFINE
CLASS ステートメントの OBJECT 節に指定されているものと同じローカルデータエリアを使用してください。
GLOBAL 節、LOCAL 節、および INDEPENDENT 節は、他の任意の Natural プログラムで使用できます。
技術的には可能ですが、通常はメソッドサブプログラムで CONTEXT 節を使用することは意味がありません。
次の例は、特定の人物に関するデータをテーブルから検索します。検索キーは BY VALUE パラメータとして渡されます。結果のデータは、"BY REFERENCE" パラメータで返されます。"BY REFERENCE" はデフォルト定義です。メソッドの戻り値は BY VALUE
RESULT 指定によって定義されます。

ローカルの Natural セッションで作成されたオブジェクトは、同じ Natural セッションの他のモジュールからアクセスできます。
CREATE
OBJECT ステートメントは、特定のクラスのオブジェクト(インスタンスとも呼ばれます)を作成するために使用します。
Natural プログラムのオブジェクトを参照するには、オブジェクトハンドルを DEFINE
DATA ステートメントで定義する必要があります。オブジェクトのメソッドは SEND
METHOD ステートメントで呼び出されます。オブジェクトにはプロパティを指定できます。プロパティには通常の割り当て構文を使用してアクセスできます。
次の手順について説明します。
Natural プログラムのオブジェクトを参照するには、オブジェクトハンドルを DEFINE DATA ステートメントで次のように定義する必要があります。
DEFINE
DATA |
level-handle-name [(array-definition)] HANDLE OF
OBJECT |
| ... |
END-DEFINE |
例:
DEFINE DATA LOCAL 1 #MYOBJ1 HANDLE OF OBJECT 1 #MYOBJ2 (1:5) HANDLE OF OBJECT END-DEFINE
クラスのインスタンスを作成するには
CREATE
OBJECT ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
オブジェクトの特定メソッドを呼び出すには
SEND
METHOD ステートメントを使用します。詳細については『ステートメント』ドキュメントを参照してください。
プロパティには、次のように ASSIGN(または COMPUTE)ステートメントを使用してアクセスできます。
ASSIGNoperand1.property-name = operand2 |
ASSIGNoperand2 = operand1.property-name |
operand1 はオブジェクトハンドルとして定義する必要があり、プロパティがアクセスされるオブジェクトを識別します。オブジェクトがすでに存在している必要があります。
operand2 として、プロパティのフォーマットに対してデータ転送互換を必要とするフォーマットのオペランドを指定します。詳細については、データ転送の互換性規則の説明を参照してください。
オブジェクトのプロパティの名前です。
プロパティ名が Natural 識別子構文に対応する場合は、次のように指定できます。
create object #o1 of class "Employee" #age := #o1.Age
プロパティ名が Natural 識別子構文に対応しない場合は、次のように山カッコで囲む必要があります。
create object #o1 of class "Employee" #salary := #o1.<<%Salary>>
プロパティ名は、インターフェイス名で修飾することもできます。同じ名前のプロパティが含まれる複数のインターフェイスがオブジェクトにある場合は、修飾が必要になります。この場合、修飾したプロパティ名は山カッコで囲む必要があります。
create object #o1 of class "Employee" #age := #o1.<<PersonalData.Age>>
例:
define data local 1 #i (i2) 1 #o handle of object 1 #p (5) handle of object 1 #q (5) handle of object 1 #salary (p7.2) 1 #history (p7.2/1:10) end-define * ... * Code omitted for brevity. * ... * Set/Read the Salary property of the object #o. #o.Salary := #salary #salary := #o.Salary * Set/Read the Salary property of * the second object of the array #p. #p.Salary(2) := #salary #salary := #p.Salary(2) * * Set/Read the SalaryHistory property of the object #o. #o.SalaryHistory := #history(1:10) #history(1:10) := #o.SalaryHistory * Set/Read the SalaryHistory property of * the second object of the array #p. #p.SalaryHistory(2) := #history(1:10) #history(1:10) := #p.SalaryHistory(2) * * Set the Salary property of each object in #p to the same value. #p.Salary(*) := #salary * Set the SalaryHistory property of each object in #p * to the same value. #p.SalaryHistory(*) := #history(1:10) * * Set the Salary property of each object in #p to the value * of the Salary property of the corresponding object in #q. #p.Salary(*) := #q.Salary(*) * Set the SalaryHistory property of each object in #p to the value * of the SalaryHistory property of the corresponding object in #q. #p.SalaryHistory(*) := #q.SalaryHistory(*) * end
配列が値として正しく含まれるオブジェクトハンドルとプロパティの配列を使用するためには、次の知識が重要です。
オブジェクトハンドルの配列のオカレンスのプロパティは、次のインデックス表記で指定します。
#p.Salary(2) := #salary
配列が値として含まれるプロパティは、常に全体としてアクセスされます。したがって、プロパティ名でのインデックス表記は不要です。
#o.SalaryHistory := #history(1:10)
結果的に、配列が値として含まれるオブジェクトハンドルの配列のオカレンスのプロパティは、次のように指定します。
#p.SalaryHistory(2) := #history(1:10)