Java インターフェイスで静的メソッドを定義する
-
Java
interface
のstatic
メソッド -
interface
でstatic
メソッドを使用することの重要性 -
interface
におけるstatic
メソッドの規則 -
Java 8 より前のインターフェースに
static
メソッドがない理由 -
static
メソッドをオーバーライドできない理由
このチュートリアルでは、Java interface
で static
メソッドを使用するための規則をリストし、それらを定義する方法と、それらをオーバーライドできない理由を示します。 また、Java 8 より前のインターフェースに static
メソッドがない理由についても調べます。
Java interface
の static
メソッド
Java インターフェイスの static
メソッドに入る前に、この interface
を implements
するクラスで定義された 1つまたは複数の abstract
メソッド (本体のないメソッド) を含む interface
について知っておくことが重要です。 .
これらの abstract
メソッドは public
修飾子を記述してもしなくても public
メソッドであることに注意してください。
コード例:
public interface Messages {
// public & abstract
public void display();
}
public class Test implements Messages {
// implementation of abstract method
public void display() {
System.out.println("Hi! Welcome to the DelftStack");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
出力:
Hi! Welcome to the DelftStack
display()
という名前の abstract
メソッドは public
メソッドであることを思い出してください。display()
メソッドを実行するには、Test
クラスをインスタンス化する必要があります。
一方、static
メソッドは、それらが定義されているクラス自体に関連付けられており、これらの static
メソッドを使用するためにクラスをインスタンス化する必要はありません。 Java 8 の時点で、static
インターフェイス メソッドを使用できるようになりました。
これで、完全な本体と、その特定の static
メソッドに必要なすべての命令が interface
に用意されました。 static
メソッドは、インスタンス レベルではなく、クラス レベルでのみアクセスできることに注意してください。
したがって、次のように static
メソッドにアクセスできます。
コード例:
public interface Messages {
// static method
static void display() {
System.out.println("Hello! Nice to meet you");
}
}
public class Test {
public static void main(String[] args) {
Messages.display();
}
}
出力:
Hello! Nice to meet you
問題は、static
メソッドをオーバーライドできるかどうかです。 いいえ、static
メソッドをオーバーライドすることはできません。 そうしないと、コンパイル エラーが発生します。
さらに、static
メソッドは隠されているため、実装クラスのインスタンスを介してそれらを呼び出すことはできません。 コンパイル エラーを生成する次の例を参照してください。
コード例:
public interface Messages {
static void display() {
System.out.println("Hello! Nice to meet you");
}
}
public class Test implements Messages {
@Override
public void display() {
System.out.println("Override");
}
public static void main(String[] args) {
Test test = new Test();
test.display();
}
}
以下は、上記のコード フェンスによって生成されるエラーの説明です。
出力:
Test.java:25: error: method does not override or implement a method from a supertype
@Override
^
1 error
interface
で static
メソッドを使用することの重要性
Java インターフェイスで static
メソッドを使用すると、次の利点が得られます。
interface
のstatic
メソッドは、サブクラスまたはサブインターフェースに継承またはオーバーライドさせたくない動作をカプセル化します。- Java
interface
のこれらのstatic
メソッドは、特定の実装タイプのクラスに限定されない再利用可能なユーティリティの開発に役立ちます。
interface
における static
メソッドの規則
次のセクションでは、static
メソッドを使用する場合の上記の利点のルールを示します。
インターフェイスのデフォルト メソッド はデフォルト動作の命令を保持し、実装クラスはそれをオーバーライドするか、そのまま継承することにより、より具体的な命令を提供することを選択できます。 デフォルトのメソッドと同様に、static
メソッドにはその動作の本体 (一連の命令) が含まれていますが、以前に学んだように、実装クラスはその interface
の static
メソッドを継承またはオーバーライドすることはできません。
Java interface
で static
メソッドを使用する場合は、次の規則を覚えておく必要があります。
- これらのメソッドには本体が必要です。
interface
名を使用してこれらのstatic
メソッドのみを実行できます。- これらのメソッドには、メソッドの宣言に
static
修飾子が必要です。 指定しない場合、デフォルトでpublic
になります。 必要に応じて、それらをprivate
にすることもできます。 - 他の
abstract
またはデフォルトのメソッドを呼び出すことはできません。 - サブクラスまたはサブインターフェースは、これらの
static
メソッドをオーバーライドまたは継承することはできません。
さて、この時点で、頭の中に 2つの質問があるかもしれません。
- 昔 (Java 8 のリリース前) に
static
メソッドを使用できなかったのはなぜですか? static
メソッドをオーバーライドできないのはなぜですか?
これらの両方の質問に対する答えを見つけてみましょう。
Java 8 より前のインターフェースに static
メソッドがない理由
Java インターフェースが Java 8 のリリース前に static
メソッドを持たなかった理由として、強力で主要な技術的原因はありませんでした。これらの static
メソッドは、小さな言語の更新または変更と見なされ、Java に追加するという公式の提案がありました。 7 でしたが、その後、いくつかの合併症のために削除されました。
最後に、Java 8 では、インターフェースで static
メソッドが導入されました。 Java 8 の時点で、デフォルトの実装でオーバーライド可能なインスタンス関数/メソッドについても学びました。
まだインスタンス フィールドが含まれていないことを思い出してください。 これらの機能は、ここ (JSR 335 パート H) で読むことができる lambda
式サポートの一部です。
static
メソッドをオーバーライドできない理由
static
メソッドはコンパイル時に解決されます。 動的ディスパッチは、コンパイラがオブジェクトの具体的な型を判断できないインスタンス メソッドについて意味があります。 したがって、呼び出すメソッドを解決できません。
しかし、static
メソッドを実行するにはクラスが必要です。 その特定のクラスはコンパイル時に 静的に
知られているため、動的ディスパッチは不要です。
すべてのクラスに、メソッドのシグネチャ (名前とパラメーターの型) を実際のコードにマップしてメソッドを実装する HashTable
があるとします。 VM がインスタンスでメソッドを実行しようとすると、そのクラスのオブジェクトをクエリし、クラスのテーブルで要求された署名を探します。
メソッド本体が見つかった場合に呼び出されます。 それ以外の場合は、ルックアップが繰り返されるクラスの親クラスが取得されます。 このプロセスは、メソッドが見つかるか、親クラスがなくなるまで続きます (これにより、NoSuchMethodError
が生成されます)。
それぞれのテーブルに同じメソッド シグネチャのサブクラスとスーパークラスのエントリがある場合、サブクラスのバージョンが最初に検出され、スーパークラスのバージョンは決して使用されません。これはオーバーライド
です。
オブジェクト インスタンスをスキップしてサブクラスから開始すると仮定すると、解決は上記のように進み、一種の オーバーライド可能
静的
メソッドを提供できます。 この解決は、コンパイル時にのみ発生することに注意してください。
ただし、コンパイラは、未指定の型のオブジェクトにそのクラスのクエリを実行するまで待機するのではなく、既知のクラスから開始することがわかっています。 したがって、static
メソッドをオーバーライドしても意味がありません。