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


292

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

もちろん、技術的には問題ではありません。interfaceis を実装するクラスメソッドは常にpublicです。しかし、より良い慣習は何ですか?

Java自体はこれで一貫していません。たとえば、Collectionvs Comparable、またはFuturevsを参照してくださいScriptEngine


22
パブリックとして書くと、それ非パブリックになる可能性があること暗示するので、それは悪いことです
Pacerier

8
フォームの冗長な構文は避けてください。
ローン侯爵

3
@Pacerier、publicこのコンテキストで使用するのは悪いことだと私は同意しますが、デフォルトのインターフェースメソッド(Java 9で)非公開にすることができます。コメントは廃止されているため、削除することをお勧めします。
aioobe

2
はい、Java 9で変更される可能性があります。「パブリックとして記述すると、非パブリックになる可能性があります」。それはまさにJava 9で可能であるように思われるので、この議論は今や実際に書き出すことの利益にありpublicます。
MC皇帝

回答:


334

JLSはこれが明確になります:

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


6
上記のJLSリンクは、私が読んだ時点ではJava 7用でした。非公開メソッドを許可するJava 9についてのコメントの後、私はSE9 JLSについても非常に類似した表現がまだ存在していることを確認したかっただけです。(public一部は同じ、and/or abstract一部は削除されています)
OzgurH 2018

3
まだ本当でSE11 JLS
Ortomala Lokni


44

Javaインターフェースではpublic修飾子を省略すべきです(私の意見では)。

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

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

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

3
そのようなスタイルガイドへのリンクはありますか?
Benno Richters、

9
一貫性は断然最も重要なことであり、これらのタイプの質問の99%に対する答えです。
SCdF 2008年

合意済み:一貫性。あなたのコーディング標準のための何かがみんな:)
JeeBee

2
Bno:1つの例はJava言語仕様で、もう1つはCheckstyleです。
Rasmus Faber、

9

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

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

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

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

第4に、Interfaceは定数をデータメンバーとしてのみ含めることができます。つまり、それらはfinalでなければならず、もちろん最後の定数はそれらの1つのインスタンスのみを保持するために静的として宣言されます。したがって、静的なfinalもインターフェイス定数の必須項目です。

つまり、インターフェイスのパブリック抽象ビフォアメソッドとパブリックスタティックファイナルビフォア定数を使用することは有効ですが、他のオプションがないため、冗長と見なされ、使用されません。


7

導入によりprivatestaticdefaultJavaの8/9のインターフェイスメソッドの修飾子、物事は複雑になりますし、私はその完全な宣言が(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() {}

}

5

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

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


5

public特に構文の強調表示により、コードを読みやすくするため、修飾子付きの宣言メソッドを使用しました。ただし、最新のプロジェクトでは、Checkstyleを使用しました。publicインターフェイスメソッドの修飾子ので、それらを省略するように切り替えました。

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


2
ただし、2つのチェックボックスをオンにした場合にのみ、メソッドをパブリック、抽象として宣言します。
MetroidFan2002 2008年

4

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


6
また、すべてのインターフェイスメソッドを抽象的に明示的に宣言しますか?
Dan Dyer、

4
これはインターフェースであり、抽象クラスではありません。「公開」については、考えた時点で入力した7文字です。そして、それは実装でも同様に定義されます。これは、一貫性の場合は+1で、冗長性の場合は-1とバランスをとります。
JeeBee 2008年

3

私はそれをスキップすることを好む、私はインターフェイスがデフォルトであるどこかを読んだ、publicそしてabstract

驚いたことに、この本-Head First Design Patternsは、public、インターフェイス宣言とインターフェイスメソッドでしています...もう一度考え直して、この投稿にたどり着きました。

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


1
明確にするためpublicに、インターフェイス宣言でアクセス修飾子を省略した場合、デフォルトではパブリックで抽象化されませんdocs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Jabbslad

3

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

代わりに、Javaは 'public'を指定/強制する必要があると思います。どうして?修飾子が存在しないことは、他のあらゆる場所で「パッケージ」アクセスを意味し、これを特別なケースとして持つことが混乱の原因となります。単に明確なメッセージ(たとえば、「パッケージへのアクセスはインターフェイスで許可されていません。」)を伴うコンパイルエラーにした場合、 'public'を省略するオプションを導入することで生じる明白なあいまいさを取り除くことができます。

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

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

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


2

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

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

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


しかし、保護されたアクセスを持つ抽象メソッドを抽象クラスに実装することもできます。したがって、公開は必須ではありません。デフォルトになるものと同じ明示的なものを追加することは常に冗長ですが、必ずしも役に立たないわけではありません。
swpalmer

しかし、問題はインターフェースについてです。脱線したくなかった。つまり、Java 8以降では、インターフェースのプライベートメソッドとデフォルトメソッドについても説明できます。したがって、必要に応じて、この議論をかなり長くすることができます。;)
Iuliana Cosmina

1

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

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


-9

人々は、ソースを読むのではなく、IDEまたはJavadocのコード補完からインターフェースを学習します。したがって、ソースに「公開」することには意味がありません。誰もソースを読んでいません。


8
誰もソースを読んでいないという声明に本当に同意しなければなりません。多くの人がコードを拡大するためにEclipseのインスタンスF3を使用していると思います。Mavenのようなツールは、理由のために、JavaDocだけでなく、ソースをダウンロードするオプションを提供します。
Benno Richters 2012

これは、publicアクセス修飾子をインターフェイスに追加しない正確な理由ではありません。これは仕様によるものであり、その背後で慎重に検討した結果です。
mtk
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.