Skip to main content

クラスの定義

ここでは、InterSystems IRIS® データ・プラットフォームにおけるクラス定義の基本について説明します。

用語の概要

以下に、簡単な InterSystems IRIS クラス定義と、いくつかの代表的な要素を示します。

Class Demo.MyClass Extends %RegisteredObject
{

Property Property1 As %String;

Property Property2 As %Numeric;

Method MyMethod() As %String
{
   set returnvalue=..Property1_..Property2
   quit returnvalue
}

}

以下の点に注意してください。

  • 完全なクラス名は Demo.MyClass です。パッケージ名は Demo、短いクラス名は MyClass です。

  • このクラスは、クラス %RegisteredObjectOpens in a new tab を拡張しています。同様に、このクラスは、%RegisteredObjectOpens in a new tab を継承しています。

    %RegisteredObjectOpens in a new tab は、このクラスのスーパークラスです。つまり、このクラスは、%RegisteredObjectOpens in a new tab のサブクラスになります。InterSystems IRIS クラスは、このトピックで後述するように、複数のスーパークラスを持つことができます。

    クラスのスーパークラスにより、そのクラスの用途が決まります。

  • このクラスでは、2 つのプロパティ Property1Property2 を定義しています。プロパティ Property1 のタイプは %StringOpens in a new tab です。また、プロパティ Property2 のタイプは %NumericOpens in a new tab です。

  • このクラスでは、1 つのメソッド MyMethod() を定義しています。このメソッドは、%StringOpens in a new tab タイプの値を返します。

このクラスでは、InterSystems IRIS が提供するシステム・クラスを参照しています。これに該当するクラスは、%RegisteredObjectOpens in a new tab (完全名は %Library.RegisteredObjectOpens in a new tab)、%StringOpens in a new tab (%Library.StringOpens in a new tab)、および %NumericOpens in a new tab (%Library.NumericOpens in a new tab) です。%RegisteredObjectOpens in a new tab は、オブジェクト・インタフェースを定義しているため、InterSystems IRIS の重要なクラスの 1 つといえます。これにより、オブジェクト・インスタンスを作成するメソッドとオブジェクト・インスタンスを操作するメソッドが提供されます。%StringOpens in a new tab%NumericOpens in a new tab はデータ型クラスです。そのため、それに対応するプロパティは、リテラル値を保持することになります (その他の種類の値は保持しません)。

クラスの種類

InterSystems IRIS には、クラス定義の大規模セットが用意されています。これは、以下のような一般的な方法でクラスで使用できます。

  • クラスは、クラスのスーパークラスとして使用できます。

  • クラスは、プロパティの値として、メソッドへの引数の値として、メソッドから返される値などとして使用できます。

  • 特定の API を提供するだけのクラスもあります。通常、このようなクラスは、上記のいずれの方法でも使用してはいけません。その代わりに、API のメソッドを呼び出すコードを作成してください。

スーパークラスの最も一般的な選択項目は、以下のとおりです。

  • %RegisteredObjectOpens in a new tab — このクラスは、最も汎用的な形式でオブジェクト・インタフェースを表します。

  • %PersistentOpens in a new tab — このクラスは、永続クラスを表します。オブジェクト・インタフェースを提供することに加え、このクラスは、データベースにオブジェクトを保存するためのメソッドと、データベースからオブジェクトを読み取るためのメソッドも提供します。

  • %SerialObjectOpens in a new tab — このクラスは、別のオブジェクトに埋め込み可能な (別のオブジェクト内でシリアル化できる) オブジェクトを表します。

  • 上記のクラスのいずれかのサブクラス。

  • なし — クラスを作成するときに、スーパークラスを指定する必要はありません。

プロパティの値、メソッドへの引数の値、メソッドから返される値などについて、最も一般的な選択項目は以下のとおりです。

オブジェクト・クラス

オブジェクト・クラスとは、%RegisteredObjectOpens in a new tab のサブクラスを指す語句です。オブジェクト・クラスでは、クラスのインスタンスの作成、インスタンスのプロパティの指定、およびインスタンスのメソッドの呼び出しができます。

オブジェクトとは、オブジェクト・クラスのインスタンスを指す一般的な用語です。

オブジェクト・クラスには、3 つの一般的なカテゴリがあります。

以下の図は、これら 3 つのクラス間の継承関係を示しています。ボックスには、クラスで定義されたメソッドのいくつかをリストしています。

クラス %Persistent および %SerialObject は、親クラス %RegisteredObject のメソッドを継承します。

コレクション・クラスとストリーム・クラスは、シリアル化の動作を備えたオブジェクト・クラスです。

データ型クラス

データ型クラスとは、ClassType キーワードが datatype に設定されているクラス、または、そのようなクラスのサブクラスのことを指す語句です。これに該当するクラスは、オブジェクト・クラスではありません (データ型クラスでは、プロパティを定義できません。また、クラスのインスタンスを作成できません)。データ型クラス (より厳密には、データ型ジェネレータ・クラス) の用途は、オブジェクト・クラスのプロパティのタイプとして使用することです。

クラス・メンバの種類

InterSystems IRIS クラスの定義には、以下の項目を含めることができ、これらはすべてクラス・メンバと呼ばれます。

  • パラメータ — パラメータは、このクラスによって使用される定数値を定義します。ほとんどの場合、この値はコンパイル時に設定されます。

  • メソッド — InterSystems IRIS は、インスタンス・メソッドとクラス・メソッドの 2 種類のメソッドをサポートしています。インスタンス・メソッドは、クラスの特定のインスタンスから呼び出され、そのインスタンスに関連する何らかのアクションを実行します。このタイプのメソッドは、オブジェクト・クラス内でのみ役立ちます。クラス・メソッドは、そのクラスのインスタンスがメモリ内にあるかどうかにかかわらず、呼び出すことがでます。このタイプのメソッドは、他の言語では静的メソッドと呼ばれています。

  • プロパティ — プロパティには、クラスのインスタンスのデータが格納されます。プロパティは、オブジェクト・クラスでのみ役立ちます。詳細は、以下のセクションで説明します。

  • クラス・クエリ — クラス・クエリは、クラスが使用できる SQL クエリを定義し、クエリのためのコンテナとして使用するクラスを指定します。多くの場合 (必須ではない)、永続クラスには、クラス・クエリを定義します。これは、そのクラスの保存済みデータにクエリを実行するためのものです。ただし、クラス・クエリは、どのようなクラスにでも定義できます。

  • その他の種類のクラス・メンバ (永続クラスにのみ関連するメンバ) :

    • ストレージ定義

    • インデックス

    • 外部キー

    • SQL トリガ

  • XData ブロック — XData ブロックは、クラス内に定義されたデータの名前付きユニットです。通常、クラスのメソッドで使用します。これらには、多数の用途があります。

  • プロジェクション — クラス・プロジェクションは、クラス・コンパイラの動作を拡張する方法を提供します。

    プロジェクションのメカニズムは、Java プロジェクションで使用されます。これが、プロジェクションという用語の語源です。

さまざまなクラス・メンバの定義に使用される言語 (ObjectScript、Python、SQL、その他メンバの実装に使用されるコードを除く) は、クラス定義言語 (CDL) と呼ばれることもあります。

プロパティの種類

形式上、プロパティには、属性およびリレーションシップという 2 種類のプロパティがあります。

属性は値を保持します。属性プロパティは、通常、単にプロパティと呼びます。プロパティの定義に応じて、保持できる値は、以下のいずれかにできます。

  • リテラル値 ("MyString" や 1 など)。リテラル値を保持するプロパティは、データ型クラスに基づいているため、データ型プロパティと呼ばれることもあります。"リテラル・プロパティの定義と使用" を参照してください。

  • ストリーム。ストリームとは、文字列には長すぎる値を格納するオブジェクトです。"ストリームを使用した作業" を参照してください。

  • コレクション。InterSystems IRIS には、プロパティをリストまたは配列として定義する機能があります。リストまたは配列の項目は、リテラル値になるか、オブジェクトにできます。"コレクションを使用した作業" を参照してください。

  • その他の種類のオブジェクト。"オブジェクト値プロパティの定義と使用" を参照してください。

リレーションシップは、オブジェクト間の関連付けを保持します。リレーションシップ・プロパティはリレーションシップと呼ばれます。リレーションシップは、永続クラスでのみサポートされます。"リレーションシップの定義と使用" を参照してください。

クラスの定義法:基本

このセクションでは、基本的なクラス定義について詳細に説明します。以下のトピックについて説明します。

一般に、クラスを定義するには、統合開発環境 (IDE) を使用します。クラス定義クラスまたは XML クラス定義ファイルを使用して、プログラム的にクラスを定義することもできます。SQL DDL 文を使用して SQL テーブルを定義する場合、システムはそれに対応するクラス定義を作成します。

スーパークラスの選択

クラスを定義する場合、設計上の最初の決定事項の 1 つは、独自のクラスのベースにするクラス (複数可) を選択することです。スーパークラスが 1 つのみの場合は、Extends に続けてスーパークラスの名前をクラス定義の冒頭部分に含めます。

Class Demo.MyClass Extends Superclass 
{

//...

}

スーパークラスが複数ある場合は、それらをコンマ区切りのリストとして、括弧で囲って指定します。

Class Demo.MyClass Extends (Superclass1, Superclass2, Superclass3) 
{

//...

}

クラスを作成するときに、スーパークラスを指定する必要はありません。一般に、クラスがどのような種類のオブジェクトも表現しないとしても、共通に使用される多数のマクロにクラスからアクセスできるようにするために、スーパークラスとして %RegisteredObjectOpens in a new tab を使用します。その代わりに、それらが格納されたインクルード・ファイルを直接取り込むこともできます。

インクルード・ファイル

%RegisteredObjectOpens in a new tab またはそのサブクラスを拡張しないクラスを作成するときには、以下のインクルード・ファイルを取り込むことができます。

%RegisteredObjectOpens in a new tab またはそのサブクラスを拡張するクラスの場合は、これらのマクロが自動的に利用できるようになります。

また、独自のインクルード・ファイルを作成して、そのファイルを必要に応じてクラス定義に取り込むことができます。

クラス定義の先頭にインクルード・ファイルを取り込むには、以下の形式の構文を使用します。インクルード・ファイルの拡張子 .inc は省略する必要がある点に注意してください。

Include MyMacros

例 :

Include %occInclude

Class Classname 
{
}

クラス定義の先頭に複数のインクルード・ファイルを取り込むには、以下の形式の構文を使用します。

Include (MyMacros, YourMacros) 

この構文では、先頭にシャープ記号が付かない点に注意してください (習慣的に必要とする構文とは異なります)。また、Include 指示文は、大文字と小文字が区別されません。例えば、INCLUDE を使用することも可能です。インクルード・ファイルの名前は、大文字と小文字が区別されます。

"#include" も参照してください。

クラス・キーワードの指定

場合によっては、クラス・コンパイラが生成するコードの詳細を制御することが必要になります。例えば、永続クラスについて、既定のテーブル名の使用を望まない場合 (または使用できない場合) は、SQL テーブルの名前を指定できます。もう 1 つ例を挙げると、クラスに Final のマークを付けて、そのクラスのサブクラスが作成されないようにすることもできます。クラス定義では、そのような目的に応じた特定のキーワードのセットをサポートしています。クラス・キーワードの指定が必要な場合は、以下に示すように、スーパークラスの後の角括弧でクラス・キーワードを囲みます。

Class Demo.MyClass Extends Demo.MySuperclass [ Keyword1, Keyword2, ...]
{

//...

}

例えば、使用可能なクラス・キーワードには、AbstractFinal があります。概要は、"コンパイラ・キーワードの概要" を参照してください。InterSystems IRIS には、各種のクラス・メンバに固有のキーワードも用意されています。

クラス・パラメータの定義法の概要

クラス・パラメータは、特定のクラスのすべてのオブジェクトに対する定数値を定義します。クラス・パラメータをクラス定義に追加するには、以下のいずれかのような要素をクラスに追加します。

Parameter PARAMNAME as Type;
Parameter PARAMNAME as Type = value;
Parameter PARAMNAME as Type [ Keywords ] = value;

Keywords はパラメータ・キーワードを表します。キーワードの概要は、"コンパイラ・キーワードの概要" を参照してください。パラメータ・キーワードの詳細は、"パラメータの構文とキーワード" を参照してください。これはオプションです。

プロパティの定義法の概要

オブジェクト・クラスには、プロパティを含めることができます。

プロパティをクラス定義に追加するには、以下のいずれかのような要素をクラスに追加します。

Property PropName as Classname;
Property PropName as Classname [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) [ Keywords ] ;
Property PropName as Classname(PARAM1=value,PARAM2=value) ;

PropName はプロパティの名前です。Classname はオプションのクラス名です (これを省略すると、プロパティのタイプは %StringOpens in a new tab と見なされます)。

Keywords はプロパティ・キーワードを表します。キーワードの概要は、"コンパイラ・キーワードの概要" を参照してください。プロパティ・キーワードの詳細は、"プロパティの構文とキーワード" を参照してください。これはオプションです。

プロパティで使用するクラスによっては、3 番目と 4 番目のバリエーションに示すように、プロパティ・パラメータも指定できるようになります。

プロパティ・パラメータを含める場合は、パラメータを括弧で囲み、プロパティ・キーワードの前に置きます。プロパティ・キーワードを含める場合、キーワードは角括弧で囲む点にも注意してください。

メソッドの定義法の概要

InterSystems IRIS クラスには、クラス・メソッドとインスタンス・メソッドという 2 種類のメソッドを定義できます。

クラス・メソッドをクラス定義に追加するには、以下に示すような要素をクラスに追加します。

ClassMethod MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

MethodName はメソッドの名前です。また、arguments は引数のコンマ区切りリストです。Classname は、このメソッドで返される値 (ある場合) のタイプを表す、オプションのクラス名です。メソッドが値を返さない場合は、As Classname 部分を省略します。

Keywords はメソッド・キーワードを表します。キーワードの概要は、"コンパイラ・キーワードの概要" を参照してください。メソッド・キーワードについては、"クラス定義リファレンス" の Method キーワードを参照してください。これはオプションです。

インスタンス・メソッドを追加するには、同じ構文で ClassMethod の代わりに Method を使用します。

Method MethodName(arguments) as Classname [ Keywords]
{
//method implementation
}

インスタンス・メソッドは、オブジェクト・クラスでのみ存在価値があります。

名前付け規約

クラスおよびクラス・メンバは、ここで概要を説明する名前付け規約に従います。

詳細は、"識別子のルールとガイドライン" および "ネームスペースで何にアクセス可能か" を参照してください。

一般的なルール

すべての識別子は、そのコンテキスト内で一意であることが必要です (例えば、指定されたネームスペース内で 2 つのクラスが同時に完全に同じ名前を持つことはできません)。

大文字と小文字は区別されます。つまり、名前の大文字と小文字が正確に一致している必要があります。また、2 つのクラスに、大文字と小文字が異なるだけの同じ名前を付けることはできません。例えば、識別子 id1ID1 は一意性を保つ目的からは同一と見なされます。

クラス名

完全なクラス名は、パッケージ名とクラス名の 2 つの部分で構成されています。名前の中で最後の . 文字以降がクラス名になります。クラス名はそのパッケージ内で一意でなければならず、パッケージ名も InterSystems IRIS ネームスペース内で一意である必要があります。完全なクラス名 (つまり、パッケージ名で開始される名前) は、文字または % 記号で始まる必要があります。% 記号で始まるパッケージ名を持つクラスはいずれも、すべてのネームスペース内で利用できます。

永続クラスは自動的に SQL テーブルとして投影されるので、クラス定義は SQL 予約語ではないテーブル名を指定する必要があります。永続クラスの名前が SQL 予約語である場合、クラス定義は SQLTableName キーワードに対して予約語でない有効な値を指定する必要もあります。

パッケージの詳細は、"パッケージのオプション" を参照してください。

クラス・メンバ名

すべてのクラス・メンバ (プロパティやメソッドなど) の名前は、そのクラスの範囲で一意である必要があります。異なるタイプのメンバであるとしても、2 つのメンバに同一の名前を付与しないことを強くお勧めします。予期しない結果が生じる可能性があります。

さらに、永続クラスのメンバは、そのメンバの識別子として SQL 予約語を使用できません。ただし、そのメンバの SQLName または SQLFieldName キーワードを使用して、別名を定義することはできます (適切な場合)。

メンバ名の範囲を指定できます。これにより、それ以外では許可されない文字をメンバ名に使用できます。範囲指定したメンバ名を作成するには、名前の最初と最後の文字に二重引用符を使用します。以下はその例です。

Property "My Property" As %String;

継承

InterSystems IRIS クラスは、既存のクラスを継承できます。あるクラスを別のクラスから継承する場合、継承して発生するクラスをサブクラスと呼び、その派生元のクラスをスーパークラスと呼びます。

2 つのスーパークラスを使用するクラス定義の例を以下に示します。

Class User.MySubclass Extends (%Library.Persistent, %Library.Populate)
{
}

スーパークラスからメソッドを継承するクラスに加え、プロパティはシステム・プロパティの動作クラスから追加のメソッドを継承します。また、データ型属性の場合は、データ型クラスから継承します。

例えば、以下の Person という定義済みクラスがあるとします。

Class MyApp.Person Extends %Library.Persistent
{
Property Name As %String;
Property DOB As %Date;
}

このクラスから、新規クラスの Employee を容易に派生できます。

Class MyApp.Employee Extends Person
{
Property Salary As %Integer;
Property Department As %String;
}

この定義は、Employee クラスを Person クラスのサブクラスとして確立するものです。独自のクラス・パラメータやプロパティ、メソッドに加え、Employee クラスは Person クラスからのすべての要素を含みます。

サブクラスの使用

スーパークラスを使用するすべての場所で、サブクラスを使用できます。例えば、上で定義した Employee クラス、および Person クラスを使用すると、Employee オブジェクトを開いて、Person として参照できます。

 Set x = ##class(MyApp.Person).%OpenId(id)
 Write x.Name

以下のように、Employee 固有の属性、またはメソッドにもアクセスできます。

 Write x.Salary // displays the Salary property (only available in Employee instances)

プライマリ・スーパークラス

サブクラスの拡張元の中で最も左側にあるスーパークラスを、そのサブクラスのプライマリ・スーパークラスと呼びます。クラスはそのプライマリ・スーパークラスのすべてのメンバを継承します。このメンバには、該当のクラス・キーワード、プロパティ、メソッド、クエリ、インデックス、クラス・パラメータ、継承したプロパティと継承したメソッドのパラメータとキーワードなどがあります。Final としてマークされている項目を除き、継承したメンバの特性をサブクラスでオーバーライドできます (削除はされません)。

Important:

インデックス (永続クラスのオプション) は、プライマリ・スーパークラスからのみ継承されます。

多重継承

多重継承によって、クラスの動作やクラス・タイプを複数のスーパークラスから継承できます。多重継承を構築するには、括弧内に複数のスーパークラスをリストします。一番左側にあるスーパークラスがプライマリ・スーパークラスになります。

例えば、クラス X がクラス ABC から継承する場合、その定義は以下のようになります。

Class X Extends (A, B, C) 
{
}

クラス・コンパイラの既定の継承順序は左から右なので、スーパークラスどうしでメンバ定義に相違がある場合は、最も左に記述されたスーパークラスを優先することで解決されます (この例では、ABC よりも優先し、BC よりも優先します)。

具体的には、クラス X の場合、クラス・パラメータ値、プロパティ、およびメソッドの値は、クラス A (リストの先頭にあるスーパークラス) から継承され、次にクラス B、最後にクラス C から継承されます。また、X は、A で定義されていないクラス・メンバを B から継承し、A でも B でも定義されていないクラス・メンバを C から継承します。A から既に継承したクラス・メンバと同じ名前のメンバが B にある場合、X では A から継承した値を使用します。同様に、A または B のいずれかから継承したクラス・メンバと同じ名前のメンバが C にある場合は、ABC の優先順位で値を使用します。

既定では左から右への継承になるため、継承順序を指定する必要はありません。そのため、前述のクラス定義の例は、次の場合と等しくなります。

Class X Extends (A, B, C) [ Inheritance = left ]
{
}

スーパークラス間で右から左への継承を指定するには、以下のように Inheritance キーワードを使用して right の値を指定します。

Class X Extends (A, B, C) [ Inheritance = right ]
{
}

右から左への継承では、複数のスーパークラスが同じ名前のメンバを持つ場合、右側のスーパークラスにあるメンバの値が優先します。

Note:

右から左への継承でも、最も左に記述したスーパークラス (最初のスーパークラスと呼ばれることもあります) がプライマリ・スーパークラスであることは変わりません。つまり、サブクラスは最も左にあるスーパークラスからクラス・キーワード値のみを継承します。この動作はオーバーライドされません。

例えば、クラス AB、および C から X が右から左への継承順序で継承する場合に、クラス AB からそれぞれ継承したメンバ間に競合があると、既に継承済みのメンバをクラス B のメンバでオーバーライド (置換) します。クラス AB のメンバに対するクラス C のメンバの関係も同様です。クラス X のクラス・キーワードは独占的にクラス A から継承されます。左から右への継承順序でクラス A を拡張してから B を拡張した結果と、右から左への継承順序でクラス B を拡張してから A を拡張した結果が異なるのはこのためです。いずれの定義でもキーワードは最も左のスーパークラスから継承するので、この 2 つの場合で相違が発生します。

追加のトピック

"%ClassName() および最も適切なタイプのクラス (MSTC)" も参照してください。

コンパイラ・キーワードの概要

"クラスの定義法:基本" に示したように、クラス定義またはクラス・メンバの定義にキーワードを含めることができます。クラス属性とも呼ばれる、これらのキーワードは、一般にコンパイラに影響を与えます。このセクションでは、一般的なキーワードと、それらのキーワードを InterSystems IRIS が提供する方法について説明します。

以下の例では、クラス定義と一般的に使用されるキーワードを示しています。

/// This sample persistent class represents a person.
Class MyApp.Person Extends %Persistent [ SqlTableName = MyAppPerson ]
{

/// Define a unique index for the SSN property.
Index SSNKey On SSN [ Unique ];

/// Name of the person.
Property Name As %String [ Required ];

/// Person's Social Security number.
Property SSN As %String(PATTERN = "3N1""-""2N1""-""4N") [ Required ];

}

この例では、以下のキーワードを示しています。

  • クラス定義では、Extends キーワードがこのクラスの継承元のスーパークラスを指定します。

    別の方法でクラスを表示すると、Extends キーワードの名前が異なるので注意が必要です。"クラス・ドキュメントの作成" を参照してください。

  • クラス定義では、SqlTableName キーワードは、既定の名前が使用されない場合に関連付けられたテーブルの名前を決定します。このキーワードは永続クラスに対してのみ意味があります (このドキュメントで後述します)。

  • インデックス定義では、Unique キーワードにより、InterSystems IRIS はインデックスが基にしたプロパティ (この例では SSN) に対して一意性を強制します。

  • 2 つのプロパティでは、Required キーワードにより、InterSystems IRIS はプロパティに NULL 以外の値を要求します。

PATTERN はキーワードでなく、プロパティ・パラメータです。PATTERN は角括弧ではなく括弧で囲まれる点に注意してください。

ストレージに関連するキーワードは別として (これは、ほとんどドキュメント化されていません)、キーワードの詳細は "クラス定義リファレンス" で調べられます。通常の編集モードでクラスを表示すると、このリファレンス情報には、適用される構文の用例が示されます。

関連項目

FeedbackOpens in a new tab