オーバーロードは、複数の実装でメソッド名をオーバーロードするプログラミング技術です。
例えば、CalculateBill というメソッドがあり、購入品のリストをパラメーターとして取るとします。また、このメソッドの変化形を使用できます。この変化形には、購入品のリストの他に割引コードを表す別のパラメーターがあります。2 つのメソッドでは同じ名前を使用できます。メソッドを呼び出すと、割引コードのパラメーターの有無に基づき必要なメソッドが選択されます。
マネージ COBOL では、指定のクラスやインターフェイスが同じ名前のメソッドを複数使用することが許可されており (非常に一般的な方法)、署名を別にすることでそれぞれが区別されます。メソッドの署名は、次の内容で決まります。
COBOL または他の言語で記述されるコードが一部のクラスやインターフェイスでメソッドを呼び出す際に特定の名前のメソッドが複数存在する場合、利用可能なメソッドが選択されます。選択は、パラメーターの数と、パラメーターに「最適な」タイプの一致に基づきます (「最適な」の正確な定義は複雑であるため、後ほど説明します)。適切な署名のメソッドが見つからない場合、method not found (メソッドが見つからない) エラーが生じます。この名前が付いた他のすべてのメソッドよりも適切な一致を提供するメソッドがない場合、ambiguous match (曖昧な一致) エラーが表示されます。
RETURNING 項目のタイプがメソッドの署名の一部である場合、呼び出されるメソッドの選択は、決して RETURNING タイプには基づきません。これは .NET と JVM で異なるため、クラスでは、RETURNING タイプだけが異なるメソッドを複数使用できます。これは、一般的に適切な方法ではありません。単一クラス内でこのようなメソッドが複数見つかった場合、COBOL でエラーが生成されます。このような複数のメソッドが COBOL プログラムで生じるのは、明示的な演算子と暗黙的な演算子の場合のみです。
COBOL パラメーターのタイプは、次の方法で指定できます。
参照パラメーターおよび出力パラメーターの場合、マネージ タイプは、相当するマネージ タイプへのマネージ ポインターとして直接公開されます。マネージ タイプに相当しない COBOL データ タイプ (PIC X フィールド、グループ、BINARY-LONG 以外の数値フィールドなど) は、COBOL ポインターとして公開されます。
値パラメーターと RETURNING 項目の場合、タイプは次のように公開されます。
メソッドのオーバーロードの解決は次の 2 つの段階で行われます。
形式的には、適用できるどのメソッドのオーバーロードよりも適切なメソッドのオーバーロードが選択されます。他のどのオーバーロードよりも適切と判断される 1 つのオーバーロードがない場合、一致は曖昧と見なされ、コンパイラでエラーが生じます。
この 2 フェーズのプロセスで一意の最適な一致が生じない場合、エラー (曖昧な一致エラー) が生成されます。
まず、ターゲット クラスまたはその親クラスのいずれかに存在する、必要な名前のメソッド一式 (同一署名のメソッドを除く) から開始します。この一式から、メソッドにエンコードされる可視性属性に基づいて、呼び出し元のプログラムで表示できないメソッドは、次のように破棄されます。
次に、必要なメソッドがインスタンス メソッド (オブジェクト インスタンスに適用されるメソッド) の場合、すべての静的メソッドが破棄されます。同様に、必要なメソッドが静的メソッドの場合、すべてのインスタンス メソッドが破棄されます。
ここで、各メソッドを順番に調べ、通常の形式で適用できるかどうかを判断します。これは次のように決定されます。
参照パラメーターまたは出力パラメーターの場合、引数のタイプは、パラメーターのタイプと正確に同じでなければなりません。
値パラメーターの場合、暗黙変換が、引数のタイプから、対応するパラメーターのタイプに存在する必要があります。このような暗黙変換で切り捨てが必要な場合、このメソッドは切り捨て一致となります。
メソッドがこれらのルールに従って適用できない場合、拡張形式でのメソッドの一致が確認されます。どちらの場合も、次の内容が当てはまります。
メソッドの拡張形式は、配列パラメーターを、配列要素と同じタイプのゼロ個以上の値パラメーターで置き換えることで通常の形式から派生します。このため、パラメーターの総数は、呼び出し引数の数と同じになります。クラスに同じ拡張署名のメソッドが通常形式で既に含まれる場合、このメソッドは適用不可と判断されます。それ以外の場合、拡張形式は、上記の通常形式のテストと同様に適用可能かどうかのテストが行われます。
上記の選択手順後:
ambiguous match
method not found
引数タイプのセット (A1、A2、…An) の引数リスト A があり、2 つの適用可能なメソッドがパラメーター タイプ (P1…Pn) および (Q1、…Qn) の Mp と Mq をオーバーロードするとします。この場合、パラメーターは必要に応じて拡張形式に変換されています (上記参照)。
次に、Mp は Mq よりも適切なメソッドのオーバーロードであると言えます。どちらの場合も次の内容が当てはまります。
2 つの変換 (タイプ S からタイプ T1 およびタイプ S から T2) があるとします。T1 と T2 が次のような場合、T1 の方が適切な変換になります。
T1: | T2 が次のいずれかの場合: |
S と同じ | すべて |
binary-char |
|
binary-short |
|
binary-long |
|
binary-double |
|
それ以外の場合、どちらの変換も適切ではありません。
次の例では、提供される引数がターゲット メソッドの引数と正確に同じではない場合でも、最も固有のルールが実施される方法を示します。
class-id Class1 static. method-id main static. 01 objAnyObject object. 01 objString string. 01 objDateTime type DateTime. *> .NET COBOL * 01 objDateTime type java.util.Date. *> JVM COBOL 01 ref1 type Class1. procedure division. set ref1 to new Class1 invoke ref1::method1 *> uses variant 1 invoke ref1::method1(objAnyObject) *> uses variant 2 invoke ref1::method1(objString) *> uses variant 3 invoke ref1::method1(objDateTime) *> also uses variant 2, *> because an object of type DateTime can be assigned *> to an Object but not to a String. end method. method-id method1. *> Variant 1 (no parameters) procedure division. display "variant 1" end method. method-id method1. *> Variant 2 (object parameter) procedure division using by value objAnyObject as object. display "variant 2" end method. method-id method1. *> Variant 3 (string parameter) procedure division using by value objString as string. display "variant 3" end method. end class.
暗黙変換は、タイプ T のオブジェクトにタイプ S のオブジェクトを割り当てることができる場合、タイプ S からタイプ T に存在します。次の文に相当します。
SET obj-T TO obj-S
次のタイプの暗黙変換を利用できます。
これは、S が T と同じタイプであることを意味します。
COBOL では、通常、数値項目を他の項目に割り当てることができますが、データの損失はユーザーの責任になります。ただし、変換がメソッドのオーバーロードを目的に存在するかどうかを判断する場合、適切な変換と切り捨て変換を区別します。適切な変換とは、固定小数点と浮動小数点との間の変換で精度が失われる可能性はあってもデータの大きさは失われない変換のことです。
マネージ COBOL タイプの場合、適切な暗黙変換は次のようになります。
binary-char |
|
binary-char unsigned |
binary-char と同じ、次の内容を追加:
|
binary-short |
|
binary-short unsigned |
binary-short と同じ、次の内容を追加:
|
binary-long |
|
binary-long unsigned |
binary-long と同じ、次の内容を追加:
|
binary-double |
|
binary-double unsigned |
binary-double と同じ |
character |
|
float-short |
|
値 0 は、どの列挙タイプにも変換できます。
S と T が参照タイプの場合、次の状況で S を T に割り当てることができます。
ボックス化と呼ばれるプロセスで、どの値タイプも java.lang.Object タイプに変換できます。このプロセスの一環で、値はオブジェクト ヒープにコピーされ、参照が作成されます。
どの数値定数も、その定数のすべての値を含むことができるタイプに変換できます。例えば、値 1 は、BINARY-CHAR UNSIGNED と BINARY-CHAR のどちらにも変換できます。
ユーザー定義の暗黙変換は、S から S1 へのオプションの暗黙数値変換、結果が T1 になるユーザー定義の暗黙変換演算子の実行、T へのもう 1 つのオプションの暗黙数値変換の順で構成されます。ユーザー定義の暗黙変換演算子は、OPERATOR-ID IMPLICIT を使用して COBOL で定義され、name op_Implicit を含むメソッドが結果として作成されます。