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


publicアクセス修飾子を使用するかどうかに関わらず、Javaインタフェースのメソッドを宣言する必要がありますか?

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

Java自体は一貫していません。 例えばCollectionComparable 、またはFutureScriptEngine参照してください。



Answers



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

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




Javaインタフェースでpublic修飾子を省略する必要があります(私の意見では)。

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

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

public interface Foo{
  public void MakeFoo();
  void PerformBar();
}



この質問は長年前に尋ねられたにもかかわらず、インターフェースの定数の前にメソッドとpublic static finalの前にpublic abstractを使用する必要がない理由を包括的に説明すればわかります。

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

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

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

第4に、インターフェイスはデータメンバとして定数を含むことができます。つまり、それらは最終的なものでなければなりません。また、最終的な定数は静的として宣言されます。 したがって、static finalは、インタフェース定数の必須要素です。

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




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

だから私は何が最善かはっきりしていませんが、私が本当に好きではないことの1つは、インターフェイスメソッドでpublic abstractを使用することです。 Eclipseは、「Extract Interface」を使用してリファクタリングするときに、時にこれを行います。




私は、インタフェースがなく、私が直接実装を書いていた場合には、私が使うものを書いています。つまり、私はpublicを使います。




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

私が見た最悪ののは、 abstractと宣言されたメソッドとのインタフェースです...




デフォルトで公開されているインタフェースと抽象的なインタフェースのメソッドの理由は、私にとっては非常に論理的で明らかです。

インタフェース内のメソッドは、実装クラスに強制的に実装を提供するためのデフォルトの抽象化であり、デフォルトでは公開されているため、実装クラスはそれにアクセスできるようにします。

あなたのコードにこれらの修飾子を追加することは冗長で無駄であり、Javaの基礎知識や知識が不足しているという結論につながるだけです。




私はそれをスキップすることを好む、私はどこかのインターフェイスは、デフォルトでpublicabstractです読んでいる。

驚いたことに本のHead First Design Patternsは 、インターフェイス宣言とインターフェイスメソッドをpublicしています。これにより、私はもう一度考え直され、私はこの記事に上陸しました。

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




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

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




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() {}

}



人々はIDEやJavadocのコード補完から、ソースを読んでからではなく、あなたのインターフェースを学ぶでしょう。 だから、誰もがソースを読んでいるわけではありません。