Java
 Computer >> コンピューター >  >> プログラミング >> Java

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クラスにする(その場合、具象サブクラスが残りを実装する)

用途に応じてこれらの手法を使い分けることで、柔軟かつ安全な設計が可能になります。

  1. Javaのpack()メソッドとは?使い方とsetSize()との違いを解説

    pack()メソッドは、JavaのWindowクラスで定義されているメソッドで、フレーム内のすべてのコンポーネントがそれぞれの推奨サイズ(preferred size)以上で表示されるように、ウィンドウのサイズを自動的に調整します。 代替手段として、setSize()メソッドやsetBounds()メソッドを呼び出して、フレームのサイズを明示的に指定する方法もあります。しかし一般的には、pack()メソッドを使用する方がsetSize()よりも推奨されています。その理由は、pack()がフレームのサイズ決定をレイアウトマネージャーに委ねることができ、レイアウトマネージャーはプラットフォーム間の

  2. JavaのSwingUtilities.invokeLater()メソッドの使い方を徹底解説

    invokeLater()メソッドとはinvokeLater()メソッドは、SwingUtilitiesクラスが提供するstaticメソッドの一つで、AWTイベントディスパッチスレッド(Event Dispatch Thread)上でタスクを非同期に実行するために使用されます。このメソッドはSwingUtilities.invokeAndWait()とよく似た動作をしますが、大きな違いは、処理のリクエストをイベントキューに登録した後、すぐに呼び出し元へ制御を返すという点です。つまり、invokeLater()は引数で渡されたRunnableオブジェクト内のコードブロックの実行完了を待ちません。