継承とは、あるインタフェースで定義したオペレーションを、別のインタフェースに引き継ぐことを可能にするための定義です。オペレーションなどを引き継ぐ元のインタフェースのことをベースインタフェースと呼びます。継承するインタフェースは、ベースインタフェースのスコープ名をコロン(“:”)に続いて指定します。
継承の指定例を以下に示します。
この例では、インタフェース“A”がベースインタフェースです。ベースインタフェースを複数指定するときはカンマ(,)で区切って定義してください。
interface A {
long op1(in long a);
};
interface B:A {
long op2(in long b);
};
ベースインタフェースを継承したインタフェースでは、新しい要素(定数、型、例外、属性、オペレーション)を追加して宣言することができます。継承元のインタフェースで定義した同じ名前の型、定数、および例外が再定義できます。2つ以上のインタフェースを継承する場合、継承元の同じ識別子があると継承できません。
interface A {
const long a = 10;
};
interface B:A {
const long a = 100;
long op(in long A::a);
};
“継承するインタフェース”で指定されたインタフェースを直接のベースと呼びます。また、ベースインタフェースがさらに、別のインタフェースを継承する場合、このインタフェースを間接のベースと呼びます。以下の例では、インタフェース“C”から見た場合に、インタフェースBが直接のベース、インタフェースAが間接のベースとなります。
interface A { ... };
interface B:A { ... };
interface C:B { ... };
インタフェースは、複数の直接のベースから継承することができます。この継承の方法を多重継承と呼びます。直接のベースを指定する順番を変えても、継承されるインタフェースは同じものになります。多重継承の指定例を以下に示します。
interface A { ... };
interface B:A { ... };
interface C:A { ... };
インタフェースの継承で、1つのインタフェースが直接のベースとして2回指定されることはありません。
しかし、間接のベースとして複数回指定されることはあります。間接のベースとして複数回指定される例を以下に示します。
interface A { ... };
interface B:A { ... };
interface C:A { ... };
interface D:B,C { ... };
これらのインタフェースの関係を以下に示します。
B → A
↑ ↑
D → C
ベースインタフェースの要素への参照に、あいまいさがあってはなりません。ベースインタフェースの要素に同名の定数、型、例外が存在すると、あいまいさが生じる原因となります。あいまいさが生じる例を以下に示します。この例では、インタフェースCのXの型にあいまいさが生じます。
interface A {
typedef long X;
};
interface B {
typedef short X;
};
interface C:A,B {
const X = 100;
};多重継承の場合、ベースインタフェースで定数、型、例外が再定義されても、継承されるオペレーションや属性のシンタックスは変わりません。以下に例を示します。
module Module1 {
const long L = 3;
interface A {
typedef float s[L];
void f(in s para); // Sは3つのfloatからなります
};
interface B {
const long L = 4;
};
interface C:B,A { }; // f()のシグネチャは?
};
インタフェースAを定義した時点で、定数Lの実体との結びつきが決まるので、インタフェースCにおけるオペレーションfの形式は、
typedef float s[3];
void f(in s para);
と、インタフェースAと同じになります。この規則のために、導出されたインタフェースの中で定数、型、例外を再定義したとしても、ベースインタフェースから継承したオペレーションや属性への影響はありません。