8.24 2 コンポーネントの総称参照 Com_Owner、Com_AncestorおよびCom_Self
Com_Owner
Com_OwnerはRDMLXで頻繁に使用され、コマンドが指定されているオブジェクトを常に示す変数です。
デザイナーを使ってコンポーネントにコントロールを追加する場合や、イベントまたはメソッド・ルーチンを作成する場合、エディターで生成されたソース・コードでは、総称名#COM_OWNERは現在編集中のコンポーネントを指します。
Define_Com Class(#PRIM_LABL) Name(#Label) Parent(#COM_OWNER)
Evtroutine Handling(#Com_Owner.Initialize)
#Com_owner.Prepare
Endroutine
多くのプログラムで現在位置を参照する必要があるので、総称のCom_ownerを使用することで、'ここ'であることが示され、プログラムが非常に理解しやすくなります。またコードをコピーして、コンポーネントの特定クラス名への参照を更新せずに、直接ターゲットに貼り付けることが可能になります。
単一レベルを超える継承が使用されていない、比較的簡素なアプリケーションでは、このCom_Ownerを使用します。複数層の継承が使用されている場合は、Com_AncestorとCom_Selfを使用して、継承の階層構造の異なる層で定義されたプログラムを実行します。
Com_Ancestor
Com_Ancestorは現在のコンポーネントの祖先として指定されたクラスを直接参照します。
継承を使用するアプリケーション内のベースの祖先クラスで基本的な動作を定義し、継承クラス内でメソッドを再定義することで、この動作の上書きをすることが可能になります。そして祖先クラスの処理は実行時に無視され、再定義されたメソッドが実行されます。
Mthroutine Name(Prepare) Options(*Redefine)
* Class specific processing
Endroutine
通常はこの再定義メソッドの使用が望ましいです。ただし、処理を全く変更するというよりも、少しだけ拡張したいという場面もあるでしょう。これを可能にするには、次のようなコードを書きます。
Mthroutine Name(Prepare) Options(*Redefine)
#Com_Ancestor.Prepare
* Class specific processing
Endroutine
ここでは、メソッドは再定義されますが、一番最初の行の新しいメソッドで祖先バージョンのメソッドが実行されます。この技法は、祖先の処理への変更が規則的な処理ではなく、例外的な場合に使用されます。
Com_Self
Com_SelfとCom_ownerは、それぞれ独自の特徴を除いては、非常によく似ています。Com_ownerは常に現在のコンポーネントを参照するのに対し、Com_Selfは継承チェーンに遡って再定義されたメソッドも考慮に入れた上で、現在のコンポーネントを参照します。
上記のCom_ancestor例の中で、再定義メソッドは例外的な処理の場合でしたが、これが通常の処理の時は実行する祖先のコードを記憶しておく必要があり、複雑になります。このような状況では、祖先クラスから処理を操作する方が望ましいです。
つまり、祖先クラスでは以下のようになります。
Mthroutine Name(Prepare)
* ベース・コードを実行し、クラス特有のコードへ
#Com_owner.PrepareBase
#Com_Self.PrepareSelf
Endroutine
Mthroutine Name(PrepareBase) Options(*Final)
* ベースのクラス処理
* Final – このメソッドは再定義できません。
Endroutine
Mthroutine Name(PrepareSelf)
* 継承クラスで再定義
Endroutine
そして継承クラスでは、次のようなコードになります。
Mthroutine Name(PrepareSelf) Options(*Redefine)
* クラス独自の処理をここに入れます。
Endroutine
実行時、Prepareメソッドを起動すると、PrepareBaseメソッドが実行されます。PrepareSelfの起動時にCom_Selfが使われているので、実行時には継承チェーンに遡って再定義されたバージョンが検索され、祖先で定義されたバージョンではなく、このバージョンのメソッドが実行されます。
開発時に誤ってCom_SelfではなくCom_ownerが使用されているケースがよく見かけられ、再定義されたプログラムが実際には実行されないということがありますので、注意してください。