web-dev-qa-db-ja.com

インターフェイスメソッドにボディを含めることはできますか?

インターフェイスは100%純粋な抽象クラスのようなものであることを知っています。そのため、メソッドを実装することはできません。しかし、奇妙なコードを見ました。誰でも説明できますか?

コードスニペット:

 interface Whoa {
        public static void doStuff() {
            System.out.println("This is not default implementation");
        }
 }

編集:

私のIDEはIntellij Idea 13.1です。プロジェクトSDKはJava 7 <1.7.0_25>です。 IDEはコンパイラエラーを表示していません。しかし、コマンドラインでコードをコンパイルすると、次のメッセージが表示されます。

Whoa.Java:2: error: modifier static not allowed here
    public static void doStuff() {
                       ^
66
user3034861

Java 8から、デフォルトのメソッドに加えてインターフェースで静的メソッドを定義できます。

  • 静的メソッドは、オブジェクトではなく、定義されているクラスに関連付けられているメソッドです。クラスのすべてのインスタンスは、静的メソッドを共有します。

  • これにより、ライブラリでヘルパーメソッドを簡単に整理できます。インターフェースに固有の静的メソッドを、別個のクラスではなく同じインターフェースに保持できます。

  • 次の例では、タイムゾーン識別子に対応するZoneIdオブジェクトを取得する静的メソッドを定義しています。指定された識別子に対応するZoneIdオブジェクトがない場合は、システムのデフォルトのタイムゾーンを使用します。 (その結果、メソッドgetZonedDateTimeを簡素化できます)

コードは次のとおりです。

public interface TimeClient {
   // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +"; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

   default public ZonedDateTime getZonedDateTime(String zoneString) {
      return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
   }    
}

こちらもご覧ください

91
Aniket Kulkarni

これはJava 8でのみ可能です。 Java7Language Specification§9.4 では、明示的に状態:

静的メソッドは抽象化できないため、インターフェイスで宣言されたメソッドが静的に宣言されている場合、コンパイル時エラーです。

そのため、Java 7では、インターフェイスに静的メソッドは存在しません

Java8Language Specification§9.4. にアクセスすると、次のように表示されます:

静的メソッドには、メソッドの実装を提供するブロック本体もあります。

そのため、Java 8にはcanが存在できることが明示的に示されています。

Java 1.7.0_45で正確なコードを実行しようとしましたが、「modifier static not here here」というエラーが表示されました。


Java8チュートリアルから直接引用しています デフォルトのメソッド(Java言語の学習>インターフェースと継承)

静的メソッド

デフォルトのメソッドに加えて、インターフェイスで staticメソッド を定義できます。 (静的メソッドは、オブジェクトではなく、定義されたクラスに関連付けられたメソッドです。クラスのすべてのインスタンスは、静的メソッドを共有します。)これにより、ライブラリ内でヘルパーメソッドを整理しやすくなります。インターフェースに固有の静的メソッドを、別個のクラスではなく同じインターフェースに保持できます。次の例では、タイムゾーン識別子に対応する ZoneId オブジェクトを取得する静的メソッドを定義しています。指定された識別子に対応するZoneIdオブジェクトがない場合、システムのデフォルトのタイムゾーンが使用されます。 (その結果、メソッドgetZonedDateTimeを単純化できます):

public interface TimeClient {
    // ...
    static public ZoneId getZoneId (String zoneString) {
        try {
            return ZoneId.of(zoneString);
        } catch (DateTimeException e) {
            System.err.println("Invalid time zone: " + zoneString +
                "; using default time zone instead.");
            return ZoneId.systemDefault();
        }
    }

    default public ZonedDateTime getZonedDateTime(String zoneString) {
        return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
    }    
}

クラスの静的メソッドのように、インターフェイスのメソッド定義が静的メソッドであることを指定するには、メソッドシグネチャの先頭にstaticキーワードを使用します。静的メソッドを含む、インターフェイス内のすべてのメソッド宣言は暗黙的にpublicであるため、public修飾子を省略できます。

19

Javaバージョン7以下の場合、同様に機能的には、インターフェース本体内で宣言されたネストされたクラスを使用して実現できます。そして、このネストされたクラスは外部インターフェースを実装します。

例:

interface I1{
    public void doSmth();

    class DefaultRealizationClass implements  I1{

        @Override
        public void doSmth() {
           System.out.println("default realization");
        }
    }
}

コードでどのように使用しますか?

class MyClass implements I1{

    @Override
    public void doSmth() {
         new I1.DefaultRealizationClass().doSmth();
    }   
}

したがって、インターフェイス内にカプセル化されたデフォルトの実装。

13
gstackoverflow