Javaインターフェースの実装時にオーバーライドするのは1つのメソッドだけでよい?ルールと対処法を解説
Javaインターフェースとは
Javaにおけるインターフェースは、メソッドのプロトタイプ(宣言)を定義する仕様です。プログラマーに実装の指針を与えたり、ある型のメソッドやフィールドが「どのようなものであるべきか」という契約(コントラクト)を明確にしたい場合に、インターフェースを定義します。
この型のオブジェクトを生成するには、インターフェースを実装したクラスを作成し、インターフェースが持つすべての抽象メソッドに本体(処理内容)を提供する必要があります。その後、実装クラスのインスタンスを取得することで、オブジェクトとして利用できるようになります。
通常の実装例
以下は、3つの抽象メソッドを持つインターフェースを、すべて実装した例です。
interface Sample {
void demoMethod1();
void demoMethod2();
void demoMethod3();
}
public class InterfaceExample implements Sample {
public void demoMethod1() {
System.out.println("This is demo method-1");
}
public void demoMethod2() {
System.out.println("This is demo method-2");
}
public void demoMethod3() {
System.out.println("This is demo method-3");
}
public static void main(String args[]) {
InterfaceExample obj = new InterfaceExample();
obj.demoMethod1();
obj.demoMethod2();
obj.demoMethod3();
}
}
出力:
This is demo method-1 This is demo method-2 This is demo method-3
抽象メソッドを1つでも実装しないとコンパイルエラーになる
インターフェースを実装する際、そのすべての抽象メソッドをオーバーライドすることが必須です。もし1つでもオーバーライドを省略すると、コンパイル時にエラーが発生します。
エラーになる例
interface Sample {
void demoMethod1();
void demoMethod2();
void demoMethod3();
}
public class InterfaceExample implements Sample {
public void demoMethod1() {
System.out.println("This is demo method-1");
}
public void demoMethod2() {
System.out.println("This is demo method-2");
}
public static void main(String args[]) {
InterfaceExample obj = new InterfaceExample();
obj.demoMethod1();
obj.demoMethod2();
}
}
出力:
InterfaceExample.java:6: error: InterfaceExample is not abstract and does not override abstract method demoMethod3() in Sample
public class InterfaceExample implements Sample{
^
1 error
どうしても1つのメソッドだけを実装したい場合の対処法
とはいえ、「実際に処理を書きたいのは特定の1つのメソッドだけ」というケースもあるでしょう。そのような場合は、以下の2つの方法で対応できます。
方法1:残りのメソッドを空の本体で実装する
残りのメソッドを完全に未実装のままにすることはできませんが、空の本体(何も処理しない実装)を与えることで、事実上1つのメソッドにだけ処理を記述できます。
interface Sample {
void demoMethod1();
void demoMethod2();
void demoMethod3();
}
public class InterfaceExample implements Sample {
public void demoMethod1() {
System.out.println("This is demo method-1");
}
public void demoMethod2() {
}
public void demoMethod3() {
}
public static void main(String args[]) {
InterfaceExample obj = new InterfaceExample();
obj.demoMethod1();
obj.demoMethod2();
obj.demoMethod3();
}
}
出力:
This is demo method-1
方法2:残りのメソッドをdefaultメソッドにする(Java 8以降)
Java 8以降では、インターフェースにデフォルト実装を持つdefaultメソッドを定義できます。defaultメソッドは実装クラスでのオーバーライドが必須ではないため、残りのメソッドをインターフェース側でdefaultとして宣言しておけば、実装クラスでは必要な1つのメソッドだけをオーバーライドすればよくなります。
interface Sample {
void demoMethod1();
default void demoMethod2() {
System.out.println("Default demo method 2");
}
default void demoMethod3() {
System.out.println("Default demo method 3");
}
}
public class InterfaceExample implements Sample {
public void demoMethod1() {
System.out.println("This is demo method-1");
}
public static void main(String args[]) {
InterfaceExample obj = new InterfaceExample();
obj.demoMethod1();
obj.demoMethod2();
obj.demoMethod3();
}
}
出力:
This is demo method-1 Default demo method 2 Default demo method 3
まとめ
結論として、インターフェースを実装するクラスは、原則としてすべての抽象メソッドをオーバーライドしなければなりません。ただし、「実際の処理は1つのメソッドにだけ持たせたい」のであれば、次のいずれかの方法で対応可能です。
- 残りのメソッドを空の本体で実装する
- インターフェース側で残りのメソッドをdefaultメソッドとして宣言する(Java 8以降)
- 実装クラス自身をabstractクラスにする(その場合、具象サブクラスが残りを実装する)
用途に応じてこれらの手法を使い分けることで、柔軟かつ安全な設計が可能になります。
-
Javaのpack()メソッドとは?使い方とsetSize()との違いを解説
pack()メソッドは、JavaのWindowクラスで定義されているメソッドで、フレーム内のすべてのコンポーネントがそれぞれの推奨サイズ(preferred size)以上で表示されるように、ウィンドウのサイズを自動的に調整します。 代替手段として、setSize()メソッドやsetBounds()メソッドを呼び出して、フレームのサイズを明示的に指定する方法もあります。しかし一般的には、pack()メソッドを使用する方がsetSize()よりも推奨されています。その理由は、pack()がフレームのサイズ決定をレイアウトマネージャーに委ねることができ、レイアウトマネージャーはプラットフォーム間の
-
JavaのSwingUtilities.invokeLater()メソッドの使い方を徹底解説
invokeLater()メソッドとはinvokeLater()メソッドは、SwingUtilitiesクラスが提供するstaticメソッドの一つで、AWTイベントディスパッチスレッド(Event Dispatch Thread)上でタスクを非同期に実行するために使用されます。このメソッドはSwingUtilities.invokeAndWait()とよく似た動作をしますが、大きな違いは、処理のリクエストをイベントキューに登録した後、すぐに呼び出し元へ制御を返すという点です。つまり、invokeLater()は引数で渡されたRunnableオブジェクト内のコードブロックの実行完了を待ちません。