web-dev-qa-db-ja.com

Javaインターフェイスのメソッドは、パブリックアクセス修飾子を使用して、または使用せずに宣言する必要がありますか?

Javaインターフェイスのメソッドは、publicアクセス修飾子を使用して、または使用せずに宣言する必要がありますか?

もちろん、技術的には重要ではありません。 interfaceを実装するクラスメソッドは、常にpublicです。しかし、より良いコンベンションは何ですか?

Java自体はこれに一貫性がありません。たとえば、Collection vs. Comparable、またはFuture vs. ScriptEngineを参照してください。

282
Benno Richters

JLS はこれを明確にします:

インターフェイスで宣言されたメソッドに対してpublicおよび/またはabstract修飾子を冗長に指定することは許可されていますが、スタイルの問題として推奨されていません。

323
Jon Skeet

Public修飾子は、Javaインターフェイスでは省略されるべきです(私の意見では)。

余分な情報を追加しないため、重要なものから注意をそらすだけです。

ほとんどのスタイルガイドでは、これを省略することをお勧めしますが、もちろん最も重要なことは、コードベース全体、特に各インターフェイスについて一貫性を保つことです。次の例は、Javaに100%堪能でない人を簡単に混乱させる可能性があります。

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}
41
Rasmus Faber

この質問はずっと前に尋ねられたという事実にもかかわらず、包括的な説明により、メソッドの前にパブリック抽象を、インターフェイスの定数の前にパブリック静的ファイナルを使用する必要がない理由が明確になると思います。

まず、すべてのクラスが固有の実装を持つ、関連のないクラスのセットに共通のメソッドを指定するために、インターフェースが使用されます。したがって、他のクラスからアクセス修飾子をオーバーライドすることはできないため、アクセス修飾子をプライベートとして指定することはできません。

第二に、インターフェイスタイプのオブジェクトを開始できますが、インターフェイスは、それを実装するクラスによって実現され、継承されません。また、インターフェイスは、同じパッケージにない異なる関連クラスによって実装(実現)される可能性があるため、保護されたアクセス修飾子も無効です。そのため、アクセス修飾子については、パブリック選択のみが残されています。

第三に、インターフェイスにはインスタンス変数とメソッドを含むデータ実装がありません。実装されたメソッドまたはインスタンス変数をインターフェイスに挿入する論理的な理由がある場合、インターフェイスではなく継承階層のスーパークラスでなければなりません。この事実を考慮すると、インターフェースにはメソッドを実装できないため、インターフェースのすべてのメソッドは抽象でなければなりません。

第4に、Interfaceはデータメンバーとして定数のみを含めることができます。これは、それらが最終でなければならないことを意味します。したがって、静的ファイナルもインターフェイス定数の必須要素です。

結論として、メソッドの前にpublic abstractを使用し、インターフェイスの定数の前にpublic static finalを使用することはできますが、他のオプションがないため、冗長と見なされ、使用されません。

8
Leo The Four

Java 8/9のインターフェースメソッドのprivatestaticdefault修飾子の導入により、事態はより複雑になり、完全な宣言はより読みやすく(コンパイルするにはJava 9が必要です):

public interface MyInterface {

    //minimal
    int CONST00 = 0;
    void method00();
    static void method01() {}
    default void method02() {}
    private static void method03() {}
    private void method04() {}

    //full
    public static final int CONST10 = 0;
    public abstract void method10();
    public static void method11() {}
    public default void method12() {}
    private static void method13() {}
    private void method14() {}

}
6
Werner Thumann

デフォルトで適用される修飾子を配置することは避けます。指摘したように、それは矛盾と混乱につながる可能性があります。

最悪なのは、abstract...と宣言されたメソッドを持つインターフェイスです.

5
PhiLho

特に構文の強調表示でコードを読みやすくするため、public修飾子を使用して宣言メソッドを使用しました。しかし、最新のプロジェクトでは、インターフェイスメソッドのpublic修飾子のデフォルト構成で警告を表示するCheckstyleを使用したため、省略に切り替えました。

だから、何がベストかはよくわからないが、私が本当に嫌いなことの1つは、インターフェイスメソッドでpublic abstractを使用することです。 Eclipseは、「Extract Interface」でリファクタリングするときにこれを行うことがあります。

5
cretzel

インターフェイスがない場合に使用するものを常に記述し、直接実装を記述していました。つまり、publicを使用します。

4
JeeBee

私は一般的な答えには同意しません。一般に公開するということは、他の選択肢があることを意味するため、そこにあるべきではないということです。事実は、現在Java 9以降には他のオプションがあります。

代わりに、Javaは 'public'の指定を強制/要求する必要があると思います。どうして?修飾子が存在しないということは、他のすべての場所で「パッケージ」アクセスを意味し、これを特殊なケースとして使用すると混乱が生じるためです。明確なメッセージ(たとえば、「インターフェイスでのパッケージアクセスは許可されていません」)でコンパイルエラーにしただけの場合、「パブリック」を除外するオプションがあることによる明白なあいまいさを取り除きます。

現在の文言に注意してください: https://docs.Oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.4

「インターフェイスの本体のメソッドは、publicまたはprivate(§6.6)。アクセス修飾子が指定されていない場合、メソッドは暗黙的にパブリックになります。スタイルの問題として、インターフェース内のメソッド宣言にパブリック修飾子を冗長に指定することは許可されています。

「プライベート」ISが現在許可されていることを確認してください。最後の文はJLSから削除されるべきだったと思います。 「暗黙的にパブリック」な振る舞いが許可されたことは残念ですが、現在は下位互換性が維持され、アクセス修飾子が存在しないことはインターフェースでは「パブリック」、他の場所では「パッケージ」を意味するという混乱につながります。

3
swpalmer

スキップすることを好みます。デフォルトでは、publicabstractのインターフェイスがあることを読んでいます。

驚いたことに、この本は Head First Design Patterns で、インターフェイス宣言とインターフェイスメソッドでpublicを使用しています...

とにかく、冗長な情報は無視すべきだと思います。

3
Pradeep Sharma

インターフェースのメソッドがデフォルトでpublicおよびabstractである理由は、非常に論理的で明白なようです。

インターフェース内のメソッドは、デフォルトでは実装クラスに実装を提供することを強制する抽象であり、デフォルトではパブリックであるため、実装クラスはそのようにアクセスできます。

コードにこれらの修飾子を追加することは冗長で役に立たないため、Javaの基礎に関する知識や理解が不足しているという結論に導くことができます。

2
Iuliana Cosmina

それは完全に主観的です。冗長なpublic修飾子は、混乱のように見えるため省略します。他の人が述べたように、一貫性はこの決定の鍵です。

C#言語の設計者がこれを強制することにしたことに注目するのは興味深いことです。 C#でインターフェイスメソッドをパブリックとして宣言することは、実際にはコンパイルエラーです。一貫性はおそらく言語間では重要ではないので、これは実際にはJavaに直接関連しないと思います。

1
serg10