Java プログラミング言語のインターフェースは、クラスが実装しなければならない動作を宣言するために使用される抽象型です。これらはプロトコルに似ています。インターフェースはキーワードを使用して宣言され、メソッド シグネチャと定数宣言 (との両方として宣言された変数宣言) のみを含めることができます。Java 8 より前のすべてのバージョンでは、インターフェースのすべてのメソッドには実装 (メソッド本体) が含まれていません。Java 8 以降、[ 1 ] : 99および[ 1 ] : 7メソッドは定義に実装を持つことができます。[ 2 ]その後、Java 9 で、およびメソッドが追加されました。現在、Java インターフェースは最大 6 種類の異なる型を持つことができます。このようなインターフェースはC#にも存在します。interfacestaticfinaldefaultstaticinterfaceprivateprivate static
インターフェースはインスタンス化することはできませんが、実装されます。インターフェースを実装するクラスは、インターフェースで定義されているデフォルト以外のすべてのメソッドを実装するか、抽象クラスである必要があります。Java のオブジェクト参照は、インターフェース型として指定できます。いずれの場合も、参照はnullであるか、インターフェースを実装するオブジェクトにバインドされている必要があります。
インターフェースを使用する利点の1つは、多重継承をシミュレートできることです。Javaのすべてのクラスは、必ず1つの基底クラスjava.lang.Objectを持つ必要があります(Java型システムのルートクラスであるクラスを除く)。クラスの多重継承は許可されていません。ただし、インターフェースは複数のインターフェースを継承でき、クラスは複数のインターフェースを実装できます。
インターフェースは、さまざまな型のクラスが共有する類似点をエンコードするために使用されますが、必ずしもクラス関係を構成するものではありません。たとえば、人間とオウムはどちらも口笛を吹くHumanことができますが、これらをクラスParrotのサブクラスとして表現するのは意味がありませんWhistler。むしろ、これらは(おそらく中間クラスを持つ)クラスのサブクラスである可能性が高くAnimal、両方ともインターフェースを実装しますWhistler。
インターフェースのもう 1 つの用途は、オブジェクトのクラスの種類を知らなくても、特定のインターフェースを実装していることだけを知っていればオブジェクトを使用できることです。たとえば、口笛の音に悩まされている場合、それが人間なのかオウムなのかはわかりません。なぜなら、口笛を吹いている人がいるということしかわからないからです。呼び出しは、オブジェクトがどのようなクラスであっても、実装されているメソッドwhistler.whistle()を呼び出します。より実用的な例として、ソート アルゴリズムは型のオブジェクトを期待する場合があります。したがって、具体的な型を知らなくても、その型のオブジェクトは何らかの方法でソートできることがわかります。whistlewhistlerWhistlerComparable
例えば:
interface Bounceable { double pi = 3.1415 ;// セミコロンに注意// インターフェースメソッドは、public、abstract、final ではありません。// 通常はプロトタイプとして意図されていますが、デフォルトの実装も許可されていますvoid setBounce (); }インターフェース:
インターフェースは、以下の構文で定義されます(Javaのクラス定義と比較してください)。
[可視性] インターフェースInterfaceName [他のインターフェースを拡張] { 定数宣言抽象メソッド宣言静的メソッド宣言 }例:
public interface Interface1 extends Interface2 , Interface3 , Interface4 ;インターフェースの本体には抽象メソッドが含まれていますが、インターフェース内のすべてのメソッドは定義上抽象であるため、abstractキーワードは不要です。インターフェースは公開される動作のセットを指定するため、すべてのメソッドは暗黙的に抽象ですpublic。
したがって、シンプルなインターフェースは
public interface Predator { boolean chasePrey ( Prey p ); void eatPrey ( Prey p ); }インターフェース内のメンバー型宣言は暗黙的に静的、最終的、公開的ですが、それ以外は任意のクラスまたはインターフェース型にすることができます。[ 3 ]
インターフェースを実装するための構文は、次の式を使用します。
... InterfaceName [、別のインターフェース、別のインターフェース、...] を実装します...
クラスはインターフェースを実装することができます。例:
public class Lion extends Animal implements Predator { @Override public boolean chasePrey ( Prey p ) { // 獲物 p を追いかけるプログラミング (特にライオンの場合) }@Override public void eatPrey ( Prey p ) { // 獲物 p を食べるためのプログラミング (特にライオンの場合) } }クラスがインターフェースを実装していて、そのメソッドをすべて実装していない場合、そのクラスabstractは としてマークする必要があります。クラスが抽象クラスの場合、そのサブクラスのいずれかが未実装のメソッドを実装することが期待されますが、抽象クラスのサブクラスのいずれかがインターフェースのメソッドをすべて実装していない場合、そのサブクラス自体を再度 としてマークする必要があります。abstract
クラスは複数のインターフェースを実装できます。
public class Frog extends Animal implements Predator , Prey { // ... }インターフェースは共通のクラスメソッドを共有できます。
abstract class Animal implements LikesFood , LikesWater { boolean likes () { return true ; } }ただし、特定のクラスが同じまたは類似のインターフェースを複数回実装することはできません。
// エラー: 重複したインターフェースabstract class Animal implements Shares < Boolean > , Shares < Integer > ... { // ... }Java 言語では、インターフェースはコールバックによく使用されます[ 4 ]。Javaではクラスの多重継承が許可されておらず、メソッド (プロシージャ) を引数として渡すことも許可されていないためです。したがって、メソッドをターゲット メソッドにパラメータとして渡すには、呼び出し可能なクラスごとにターゲット メソッドの複数のバリアントを定義するのではなく、インターフェースへの参照を定義して渡すことで、パラメータ メソッドのシグネチャとアドレスをターゲット メソッドに提供するのが現在の慣習となっています。
インターフェースは、以下に説明するのと同じ式を使用して、他の複数のインターフェースを拡張できます。たとえば、
public interface VenomousPredator extends Predator , Venomous { // インターフェース本体}は合法であり、サブインターフェースを定義します。クラスとは異なり、多重継承が可能です。PredatorまたVenomous、 と は、 のように同じシグネチャを持つメソッドを定義または継承する可能性がありますkill(Prey p)。クラスが を実装すると、VenomousPredator両方のメソッドが同時に実装されます。
一般的なJavaインターフェースには以下のようなものがあります。
ComparablecompareToには、2 つのオブジェクトが等しいことを示す、または一方が他方より大きいことを示すために使用されるメソッドがあります。ジェネリクスを使用すると、実装クラスは、どのクラスインスタンスをそれらと比較できるかを指定できます。Serializableメソッドやフィールドを持たないマーカーインターフェースです。本体は空です。クラスがシリアライズ可能であることを示すために使用されます。Javadocには動作方法が記載されていますが、プログラムによる強制はありません。