目次 | 前 | 次 | 索引 | Java言語規定 第2版 |
インタフェース宣言は,メンバをクラス,インタフェース,定数及び抽象メソッドとする新しい参照型を導入する。この型は実装をもたないが,その抽象メソッドに実装を提供するクラスは,そのインタフェースを実装すると呼ぶ。
入れ子になったインタフェースは,その宣言が別のクラス又はインタフェースの本体内で起こる任意のインタフェースとする。最上位のインタフェースは,入れ子ではない一つのインタフェースとする。
9.では,すべてのインタフェースすなわち最上位の型(7.6)及び入れ子(8.5, 9.5)であるインタフェースの共通の意味について記述する。特定の種類のインタフェースへ特化した詳細は,その節で記述する。
プログラムは,関係しているクラスが共通の抽象上位クラスを共有すること又はメソッドをObject
に追加することを不要とするために,インタフェースを使用することができる。
インタフェースは,一つ又は複数の他のインタフェースの直接的拡張(direct extension)と宣言してもよい。これによって,隠ぺいされるいかなるメンバ及び定数以外の,インタフェースが拡張したすべてのメンバ型,抽象メソッド及び定数を,暗黙的に規定する。
クラスは,一つ以上のインタフェースを直接的に実装する(directly implement)と宣言してもよい。これによって,そのクラスの任意のインスタンスはインタフェースによって規定されるすべての抽象メソッドを実装する。クラスは,必然的に,その直接的上位クラス及び直接的上位インタフェースのすべてのインタフェースを実装する。この(多重)インタフェース継承は,オブジェクトがいかなる実装も共有せずに(多重の)共通的な振る舞いをサポートすることを可能とする。
宣言型をインタフェース型とする変数は,その値として,指定されたインタフェースを実装すると宣言されるクラスのインスタンスであるオブジェクト参照をもっていてよい。クラスがインタフェースのすべての抽象メソッドをたまたま実装しているのでは十分でない。そのクラス又はその上位クラスの一つは,そのインタフェースを実装することが本当に宣言されていなければならない。そうでないときには,クラスはそのインタフェースを実装するとは考えない。
InterfaceDeclaration: InterfaceModifiersopt interface Identifier ExtendsInterfacesopt InterfaceBodyインタフェース宣言中のIdentifierは,インタフェースの名前を規定する。インタフェースが取り囲むクラス又はインタフェースのどれかが,インタフェースの単純名と同じ名前ならば,コンパイル時エラーが発生する。
InterfaceModifiers: InterfaceModifier InterfaceModifiers InterfaceModifier InterfaceModifier: one of public protected private abstract static strictfpアクセス修飾子publicは,6.6で記述する。 すべての修飾子が,すべての種類のインタフェース宣言に適用できるわけではない。アクセス修飾子protected及びprivateは,直接的に取り囲んでいるクラス宣言(8.5)内のメンバインタフェースにのみ属する。また,これらは8.5.1で記述する。アクセス修飾子staticはメンバインタフェース(8.5, 9.5)にのみ属する。同じ修飾子が一つのインタフェース宣言で二回以上出現するとき,コンパイル時エラーが発生する。
abstract
インタフェースabstract
とする。この修飾子は,もはやインタフェースに対しては意味がなく,新しいプログラムでは使用しないことが望ましい。
strictfp
インタフェースstrictfp
修飾子の効果は,インタフェース宣言内のすべての型float
又は型double
表現を明示的にFP厳密にすることとする。
このことは,インタフェース内で宣言されたすべての入れ子にされた型は,暗黙に型strictfp
であるという意味を含む。
extends
節が提供されれば,宣言されるインタフェースは、他の名前付けされた各インタフェースを拡張し,したがって,他の名前付けされたインタフェースのメンバ型,メソッド及び定数を継承する。宣言されるインタフェースの直接的上位インタフェース(direct superinterface)とは,これらの名前付けされたインタフェースとする。宣言されたインタフェースを実装するクラスは,このインタフェースが拡張するすべてのインタフェースも実装することとする。
ExtendsInterfaces: extends InterfaceType ExtendsInterfaces , InterfaceType次は,明確化のために4.3の記述を繰り返す。
InterfaceType: TypeNameインタフェース宣言の
extends
節内の各InterfaceTypeは,アクセス可能なインタフェース型を名前付けしなければならない。そうでないときには,コンパイル時エラーが発生する。
型T に直接的に依存するインタフェースI は,I のextends
節中に上位インタフェースか上位インタフェース名の中の限定子のどちらか一方として記載される。次の条件のいずれかを満たす場合,インタフェースI は,参照型T に依存する。
すべてのクラスはクラスObject
の拡張だが,すべてのインタフェースが拡張となる単一のインタフェースは存在しない。
上位インタフェース(superinterface)関係は,直接的上位インタフェース関係の推移的閉包(transitive closure)とする。次のいずれかが真ならば,インタフェースK はインタフェースI の上位インタフェースとする。
インタフェースI は,K がI の上位インタフェースである時はいつもインタフェースK の下位インタフェースであると言える。
InterfaceBody:
{ InterfaceMemberDeclarationsopt }
InterfaceMemberDeclarations:
InterfaceMemberDeclaration
InterfaceMemberDeclarations InterfaceMemberDeclaration
InterfaceMemberDeclaration:
ConstantDeclaration
AbstractMethodDeclaration
ClassDeclaration
InterfaceDeclaration
;
インタフェース型Iで宣言又は継承されるメンバmの宣言の有効範囲は,入れ子になった型宣言を含むI の本体全体とする。
public
とする。これらが,インタフェースが宣言されているパッケージの外側からアクセス可能となる条件は,6.6の規則にしたがって,そのインタフェースがpublic
又はprotected
と宣言されていることとする。
throws
節をもつメソッドを,そのインタフェースが明示的に宣言しないかぎりにおいて,Object
内で宣言された,シグネチャs,返却値の型r,throws
節t をもった公開インスタンスメソッドに対応する,シグネチャs,返却値の型r,throws
節をもった公開抽象メンバメソッドm を,そのインタフェースは暗黙的に宣言する。
throws
節をもったメソッドを宣言する場合コンパイル時エラーとする。
インタフェースは,そのインタフェースが拡張するインタフェースから,フィールド,クラス,そのインタフェースが隠ぺいするフィールド及び上書きするメソッドを除いたすべてのメンバを継承する。
ConstantDeclaration: ConstantModifiersopt Type VariableDeclarators ConstantModifiers: ConstantModifier ConstantModifiers ConstantModifer ConstantModifier: one of public static finalインタフェース本体でのすべてのフィールド宣言は,暗黙的に
public
,static
及びfinal
とする。冗長だが,フィールドにこれらの修飾子を,どれか又はすべて明示的に指定してもよい。
インタフェースが,ある名前をもったフィールドを宣言する場合,フィールドの宣言は,インタフェースの上位インタフェース中の同じ名前をもったフィールドのあらゆるアクセス可能な宣言を隠ぺい(hide)するという。
同じ名前をもつ二つのフィールドを宣言するインタフェース宣言の本体は,コンパイル時エラーを発生する。
インタフェースが,同じ名前(8.3.3.3)をもつ複数のフィールドを継承する可能性がある。このような状況自体は,そのままではコンパイル時エラーを発生しない。しかしながら,インタフェースの本体内で,そのフィールドがその単純名で参照されると,コンパイル時エラーが起こる。なぜならば,そのような参照はあいまいだからである。
同じフィールド宣言がインタフェースから継承されるパスが幾つかあってよい。このような状況では,フィールドは,一回のみ継承されると考えられる,また,単純名によってあいまいさなく参照できる。
インタフェースフィールドのための初期化式が単純名によって同じフィールドへの参照を含むか,又は同じインタフェース内で,ソーステキスト上,後方に宣言されている他のフィールドへの参照を含めば,コンパイル時エラーが発生する。
は,二つのコンパイル時エラーを引き起こす。なぜならば,interface Test { float f = j; int j = 1; int k = k+1; }
j
は,j
が宣言される前に,f
の初期化の中で参照され,また,k
の初期化はk
自身を参照するからである。
微妙な点について述べると,実行時においてコンパイル時に定数を伴って初期化されるフィールドは,最初に初期化される。これは,クラス中のstatic
final
フィールド(8.3.2.1)にも適用される。これは,これらのフィールドが,デフォルト初期値(4.5.5)をもつと観察されることは,たとえひねくれたプログラムでも決してないことを意味する。詳細については,12.4.2と13.4.8を参照のこと。
キーワードthis
(15.8.3)又はキーワードsuper
(15.11.2, 15.12)が,インタフェースのフィールドのための初期化表現中に現れる場合,その発生が匿名クラス(15.9.5)の本体内でない限り,コンパイル時エラーが発生する。
この例では,インタフェースinterface BaseColors { int RED = 1, GREEN = 2, BLUE = 4; } interface RainbowColors extends BaseColors { int YELLOW = 3, ORANGE = 5, INDIGO = 6, VIOLET = 7; } interface PrintColors extends BaseColors { int YELLOW = 8, CYAN = 16, MAGENTA = 32; } interface LotsOfColors extends RainbowColors, PrintColors { int FUCHSIA = 17, VERMILION = 43, CHARTREUSE = RED+90; }
LotsOfColors
は,YELLOW
と名付けられた二つのフィールドを継承している。これ自体は,フィールドYELLOW
への単純名によるいかなる参照も含まないインタフェースと同様に問題ない。(このような参照は,フィールドのための変数初期化子内で起こることがある)
しかし,たとえインタフェースPrintColors
が値8
ではなく,値3
をYELLOW
へ与えていたものと仮定しても,インタフェースLotsOfColors
内でフィールドYELLOW
への参照があれば,あいまいと見なされる。
先の節での例において,フィールドRED
, GREEN
及びBLUE
は,インタフェースLotsOfColors
によって複数の方法,インタフェースRainbowColors
及びインタフェースPrintColors
によっても継承されるが,インタフェースLotsOfColors
中のフィールドRED
への参照は,あいまいであると見なさない。なぜならば,フィールドRED
のただ一つの実際の宣言が含まれるからである。
AbstractMethodDeclaration: AbstractMethodModifiersopt ResultType MethodDeclarator Throwsopt ; AbstractMethodModifiers: AbstractMethodModifier AbstractMethodModifiers AbstractMethodModifier AbstractMethodModifier: one of public abstractアクセス記述子
public
は,6.6で,記述される。抽象メソッド宣言の中で複数回同じ記述子が現れた場合,コンパイル時エラーが発生する。
インタフェース本体中のすべてのメソッド宣言は暗黙的にabstract
とするので,メソッド本体は,一つのセミコロンで表され,ブロックとはならない。
インタフェース本体中のすべてのメソッド宣言は暗黙的にpublic
とする。
Javaプラットフォームのより古い版との互換性のために,インタフェース中に宣言されるメソッドのためのabstract
記述子を冗長に指定することは,形式として許されているが,推奨しない。
インタフェースメソッドのためのpublic
記述子を冗長に指定することは,形式として許されているができる限り使用しないこと。
インタフェース中で宣言されるメソッドは,static
で宣言してはいけないことに注意すること。さもなければコンパイル時エラーが発生する。なぜならば,static
メソッドはabstract
になることは出来ないからである。
インタフェース中で宣言されるメソッドは,strictfp
又はnative
又はsynchronized
と宣言してはいけないことに注意すること。さもなければコンパイル時エラーが発生する。なぜならば,これらのキーワードは,インタフェース属性よりもむしろ実装の属性を記述するものだからである。しかしながら,インタフェース中で宣言されるメソッドは,インタフェースを実現するクラスの中でstrictfp
又はnative
又はsynchronized
で宣言されるメソッドによって実現してもよい。
同じシグネチャ(名前,パラメタの数及びパラメタの型(8.4.2))をもった二つのメソッドを明示的又は暗黙的に宣言するインタフェースの本体は,コンパイル時エラーとなる。しかしながら,インタフェースは,同じシグネチャ(9.4.1)をもった,幾つかのメソッドを継承してもよい。
インタフェース中で宣言されるメソッドは,final
で宣言してはいけないことに注意すること。さもなければコンパイル時エラーが発生する。しかしながら,インタフェース中に宣言されたメソッドは,インタフェースを実現するクラス中にfinal
で宣言されたメソッドによって実装されてもよい。
インタフェースの中のメソッド宣言が別のインタフェースの中のメソッドの宣言を上書きする際に,メソッドが異なる返却値の型をもつ,又は一方がある返却値の型をもち,他方がvoid
を返却値の型とする場合,コンパイル時エラーが発生する。さらに言えば,メソッド宣言は,上書きする任意のメソッドと衝突する(8.4.4)throws
節をもってはいけない。そうでなければコンパイル時エラーが発生する。
メソッドは,シグネチャ単位に上書きされる。例えば,インタフェースが,同じ名前の二つのpublic
メソッドを宣言し,下位インタフェースがそのうちの一つのメソッドを上書きする場合も,その下位インタフェースは,もう一つのメソッドを継承する。
インタフェースは,直接的上位インタフェースから,インタフェース中の宣言によって上書きされない上位インタフェースの全てのメソッドを継承する。
インタフェースは同じシグネチャ(8.4.2)をもった複数のメソッドを継承することがある。このような状況は,そのままではコンパイル時エラーを起こさない。インタフェースは全てのメソッドを継承すると見なされる。しかしながら,継承したメソッドが異なる返却値の型をもったり,一方がある返却値の型をもち,他方がvoid
を返却値の型とするような任意の二つの継承されるメソッドはコンパイル時エラーを引き起こす。(この継承の場合は,throws
節の衝突はエラーを起こさない。)同じメソッド宣言をインタフェースから継承するための幾つかのパスがあってもよい。この事実は,どんな困難も引き起こさず,そのままでは決してコンパイル時エラーを引き起こさない。
throws
節の間には,関係は要求されない。
abstract
で,いかなる実装も含まない。メソッドシグネチャを確定する以外に上書きメソッド宣言で達成できることは,メソッドの実装によって投げられるかもしれない例外を制限することがある。次に8.4.3.1で示す例の変形を示す。
class BufferEmpty extends Exception { BufferEmpty() { super(); } BufferEmpty(String s) { super(s); } } class BufferError extends Exception { BufferError() { super(); } BufferError(String s) { super(s); } } public interface Buffer { char get() throws BufferEmpty, BufferError; } public interface InfiniteBuffer extends Buffer { char get() throws BufferError; // override }
前述の例では,メソッド名interface PointInterface { void move(int dx, int dy); } interface RealPointInterface extends PointInterface { void move(float dx, float dy); void move(double dx, double dy); }
move
がインタフェースRealPointInterface
で,二つが宣言されており一つは継承されている三つの異なるシグネチャでオーバロードされている。インタフェースRealPointInterface
を実装するいかなる非abstract
クラスも,三つのメソッドシグネチャすべての実装を提供しなければならない。
static
及びpublic
としてよい。
単純名Cをもって宣言されたメンバ型が,完全に限定された名前Nをもったインタフェースの宣言内に直接的に閉じられている場合,メンバ型は完全に限定された名前N.Cをもつ。
インタフェースがある確かな名前をもったメンバ型を宣言する場合,そのフィールドの宣言は,インタフェースの上位インタフェースの中の同じ名前をもったメンバ型のアクセス可能なあらゆる宣言を隠ぺいする(hide)という。
インタフェースは,同じ名前をもった二つ以上の型宣言を継承してもよい。単純名であることにより,あいまいに継承されるクラスまたはインタフェースを参照すると,いかなる場合もコンパイル時エラーが発生する。同じ型宣言が複数のパスによってインタフェースから継承される場合,クラス又はインタフェースは,一度限り継承されると見なされる。単純名によって,あいまいさなく参照できる。
目次 | 前 | 次 | 索引 | Java言語規定 第2版 |