20.2.6 オブジェクト指向でのインタフェース
インタフェースとは,メソッドの名称,引数,および返却項目の定義の集まりです。インタフェースは,メソッドの実装を持ちません。
ファクトリオブジェクトとインスタンスオブジェクトは,それぞれインタフェースを持ちます。このインタフェースは,それぞれのオブジェクトが持つ,すべてのメソッド定義の集まりです。
インタフェースについては「COBOL2002 言語 標準仕様編」 「5.2.7 適合とインタフェース」を参照してください。
(1) インタフェースの利用
インタフェースを使用すると,クラス中の一部のメソッドだけを公開できます。例えば,プログラムAにはメソッドM1とM2だけを公開し,プログラムBにはメソッドM3とM4だけを公開することができ,誤ったメソッドの使用などを防止できます。
- (インタフェースの利用例)
-
上記の「預金口座」クラスは,五つのメソッドを持っています。
このうち,「パスワード変更メソッド」と「利息メソッド」を,預金者用のプログラムから使用させたくない場合,「引き出しメソッド」「預け入れメソッド」「残高照会メソッド」だけを含む「預金口座預金者」インタフェースを定義し,預金者用のプログラムではこのインタフェースを使用します。
このようにすると,預金者用のプログラムからは,「パスワード変更メソッド」と「利息メソッド」を隠ぺいできるため,誤ってメソッドを使用されることがありません。
このように,インタフェースを利用すると,プログラムごとに公開するメソッドの範囲を変更できます。
インタフェースは,ファクトリメソッド,インスタンスメソッドのそれぞれに定義できます。クラスがインタフェースを持っていることを,「インタフェースを実装する」といいます。例えば,クラスAのファクトリ定義がインタフェース1を持つ場合は,「クラスAのファクトリオブジェクトは,インタフェース1を実装する」といいます。
また,クラス定義が未完成であっても,そのインタフェース部分だけが決まっていれば,-Repository,Genオプションによってリポジトリファイルを作成できます。必要なリポジトリファイルを作成しておけば,リポジトリ段落に未完成のクラスの名前を指定した原始プログラムでも,コンパイルできるようになります。詳細は「33.3.2 リポジトリファイルの単独生成」を参照してください。
(2) インタフェースの定義
インタフェースは,INTERFACE-IDを使って定義します。INTERFACE-IDの詳細については,マニュアル「COBOL2002 言語 標準仕様編」 「7.5 インタフェース名段落(INTERFACE-ID)」を参照してください。
インタフェースの定義例を,次に示します。
IDENTIFICATION DIVISION. INTERFACE-ID. I-INT1. *> インタフェース名定義 PROCEDURE DIVISION. IDENTIFICATION DIVISION. METHOD-ID. METH1. *> メソッド名定義 DATA DIVISION. LINKAGE SECTION. 01 PRM1 PIC X. *> 引数定義 01 RET1 PIC X. *> 返却項目定義 PROCEDURE DIVISION USING PRM1 RETURNING RET1. : END METHOD METH1. *> メソッドの処理は定義しない IDENTIFICATION DIVISION. METHOD-ID. METH2. *> 必要なメソッドをすべて定義する : END METHOD METH2. END INTERFACE I-INT1.
(3) インタフェースの実装
クラス定義にインタフェースを実装する場合,ファクトリ定義またはインスタンス定義のIMPLEMENTS句にインタフェース名を指定します。IMPLEMENTS句に指定されたインタフェース名は,そのクラスから生成されるファクトリオブジェクトまたはインスタンスオブジェクトに実装されたインタフェースとなります。IMPLEMENTS句の詳細については,マニュアル「COBOL2002 言語 標準仕様編」 「7.7 オブジェクト段落(OBJECT)」を参照してください。
IDENTIFICATION DIVISION. CLASS-ID. CLS1. : IDENTIFICATION DIVISION. FACTORY. IMPLEMENTS F-INT1 F-INT2. *> ファクトリオブジェクトが実装する *> インタフェース名の指定 : END FACTORY. IDENTIFICATION DIVISION. OBJECT. IMPLEMENTS I-INT1 I-INT2. *> インスタンスオブジェクトが実装する *> インタフェース名の指定 : END OBJECT. END CLASS CLS1.
(4) インタフェースを使ったオブジェクトの使用
インタフェースによってインスタンスオブジェクトを使用する場合,インタフェース名を指定したオブジェクト参照を使用します。
01 OBJ-REF1 USAGE OBJECT REFERENCE I-INT1. インタフェース名 DATA DIVISION. WORKING-STORAGE SECTION. 01 I-INT-OR USAGE OBJECT REFERENCE I-INT1. *> インタフェース名を指定した *> オブジェクト参照 PROCEDURE DIVISION. INVOKE CLS1 'NEW' RETURNING I-INT-OR. *> 「CLS1」クラスのインスタンス *> オブジェクトの作成 INVOKE I-INT1-OR 'METH1'. *> インタフェースによるメソッド実行(1.)
インタフェース指定のオブジェクト参照によってメソッドを実行する場合,そのメソッドは,インタフェース定義中に定義されている必要があります。インタフェース中に定義されていないメソッドを実行しようとした場合,コンパイル時にエラーとなります。
上記の例で,メソッド「METH1」がインタフェース「I-INT1」の定義中にない場合は,インスタンスオブジェクト中に「METH1」があっても,1.のINVOKE文がコンパイル時にエラーとなります。
また,クラスに実装されていないインタフェース名を指定したオブジェクト参照を使用してメソッドを呼び出した場合,コンパイル時にエラーとなります。例えば,上記の例でCLS1のインスタンス定義にインタフェース名I-INT1の実装がない(IMPLEMENTS句に指定されていない)場合,コンパイル時に適合エラーが発生します。適合については,「20.2.7 オブジェクト指向による適合」を参照してください。