3.3 継承を使用するPL/SQLでのオーバーロードの使用
オーバーロードを使用すると、サブタイプの値を仮パラメータ、つまりスーパータイプに代入できます。この機能を代入性といいます。
オーバーロードおよび代入性については、次のルールがあります。
代入のルール
オーバーロードされたプロシージャの複数のインスタンスがプロシージャ・コールに一致する場合、次の代入ルールによって、コールされるプロシージャが判断されます。
-
オーバーロードされたプロシージャのシグネチャの唯一の違いが、一部のパラメータが同じスーパータイプ・サブタイプ階層のオブジェクト・タイプである場合、最も近い一致が使用されます。最も近い一致とは、サブタイプとスーパータイプの間の継承の深さによって判断され、少なくともすべてのパラメータが他のオーバーロードされたインスタンスと同程度に近く、少なくとも1つのパラメータがより近いことをいいます。
-
オーバーロードされた2つのメソッドのインスタンスが一致したが、1つ目のオーバーロードされたプロシージャにおいていくつかの引数の型が近く、2つ目のプロシージャにおいて他の引数の型が近い場合、セマンティック・エラーが発生します。
-
オブジェクト型階層内でいくつかのパラメータの位置が異なり、かつ他のパラメータはデータ型が異なるために暗黙的な変換が必要になる場合も、セマンティック・エラーが発生します。
3.3.1 継承によるPL/SQLファンクションの解決
継承によるPL/SQLファンクションの解決では、代入のルールに従います。
例3-9では、super_t
から始まる3つのレベルを持つ型階層を作成します。ファンクションのオーバーロードされたインスタンスが2つ含まれるパッケージがあります。これらのインスタンスは、型階層内の引数型の位置以外は同じです。起動では、型final_t
の変数を宣言してから、オーバーロードされたファンクションをコールします。
階層内でsub_t
はsuper_t
よりもfinal_t
に近いため、実行されるファンクションのインスタンスは、sub_t
パラメータを受け入れるインスタンスです。これは、代入のルールに基づいたものです。
コールするインスタンスはコンパイル時に決定されるため、渡された引数もfinal_t
であったという事実は無視されることに注意してください。宣言がv
super_t
:=
final_t(1,2,3)
であれば、引数がsuper_t
のオーバーロードされたファンクションがコールされます。
例3-9 PL/SQLファンクションと継承の解決
CREATE OR REPLACE TYPE super_t AS OBJECT (n NUMBER) NOT final; / CREATE OR REPLACE TYPE sub_t UNDER super_t (n2 NUMBER) NOT final; / CREATE OR REPLACE TYPE final_t UNDER sub_t (n3 NUMBER); / CREATE OR REPLACE PACKAGE p IS FUNCTION func (arg super_t) RETURN NUMBER; FUNCTION func (arg sub_t) RETURN NUMBER; END; / CREATE OR REPLACE PACKAGE BODY p IS FUNCTION func (arg super_t) RETURN NUMBER IS BEGIN RETURN 1; END; FUNCTION func (arg sub_t) RETURN NUMBER IS BEGIN RETURN 2; END; END; / DECLARE v final_t := final_t(1,2,3); BEGIN DBMS_OUTPUT.PUT_LINE(p.func(v)); -- prints 2 END; /
関連項目:
「継承を使用するPL/SQLでのオーバーロードの使用」を参照してください
3.3.2 継承によるPL/SQLファンクションの動的解決
継承によるPL/SQLファンクションの動的解決では、代入のルールに従います。
「継承を使用するPL/SQLでのオーバーロードの使用」を参照してください
例3-10では、ファンクションは型階層のメンバー・ファンクションをオーバーライドしているため、コールするインスタンスは実行時に決定されます。これは、「動的メソッド・ディスパッチ」で説明されている動的メソッド・ディスパッチです。
v
はsuper_t
のインスタンスですが、final_t
の値がv
に割り当てられているため、代入のルールに従ってファンクションのsub_t
インスタンスがコールされます。
例3-10 PL/SQLファンクションと継承の動的解決
-- Perform the following drop commands if you created these objects in Ex. 3-9 -- DROP PACKAGE p; -- DROP TYPE final_t; -- DROP TYPE _sub_t; -- DROP TYPE super_t FORCE; CREATE OR REPLACE TYPE super_t AS OBJECT (n NUMBER, MEMBER FUNCTION func RETURN NUMBER) NOT final; / CREATE OR REPLACE TYPE BODY super_t AS MEMBER FUNCTION func RETURN NUMBER IS BEGIN RETURN 1; END; END; / CREATE TYPE sub_t UNDER super_t (n2 NUMBER, OVERRIDING MEMBER FUNCTION func RETURN NUMBER) NOT final; / CREATE OR REPLACE TYPE BODY sub_t AS OVERRIDING MEMBER FUNCTION func RETURN NUMBER IS BEGIN RETURN 2; END; END; / CREATE OR REPLACE TYPE final_t UNDER sub_t (n3 NUMBER); / DECLARE v super_t := final_t(1,2,3); BEGIN DBMS_OUTPUT.PUT_LINE('answer:'|| v.func); -- prints 2 END; /