クラスアクセス修飾子より制限の少ないメンバーアクセス修飾子の使用はどうですか?


9

たとえば、いくつかのメンバーを持つクラスがあり、メンバーにはクラス自体よりも制限の少ないアクセス修飾子があるとします。

具体的な例は次のとおりです。

package apples;

class A { // package private
    public int foo() { // public (=> less restrictive than *package private*)
        return 42;
    }
}

メンバーアクセス修飾子よりも制限の厳しいクラスアクセス修飾子を理解すると、制限の少ないメンバーアクセス修飾子が上書きされます。したがって、制限の少ないメンバーアクセス修飾子はまったく効果がありません。

  • 私の理解は正しいですか?
    • そうでない場合、結果はどうなりますか?
  • 制限の少ないメンバーアクセス修飾子を使用する正当な理由は何ですか?
  • 最後に、従うべきベストプラクティスは何ですか?

関数の参照を渡し始めると結果に影響が出る可能性があると考えたため、いくつかの実験も行いましたが、それでもアクセス修飾子は重要ではないようです。

私が構築した状況は次のとおりです:

  • apples.Bbla()への参照を返すパブリックメソッドを提供しますapples.A.foo
  • 次に、をpizzas.C呼び出しapples.B.blaて参照を取得しA.foo、呼び出します。
  • したがって、にA.foo()は直接表示されませんがC、を介して間接的にのみアクセスできますB.bla()

私はそれをテストしましたが、foo() パッケージのアクセス修飾子をプライベートにするかどうかに関係なく、違いはありません。

package apples;

import java.util.function.IntSupplier;

public class B {
    public IntSupplier getReferenceToAFoo() {
        A aInstance = new A();
        return aInstance::foo;
    }
}
package pizzas;

import apples.B;

import java.util.function.IntSupplier;

public class C {
    private int callAFooIndirectly() {
        B bInstance = new B();
        IntSupplier intsupplier = bInstance.getReferenceToAFoo();
        return intsupplier.getAsInt();
    }

    public static void main(String[] args) {
        C cInstance = new C();

        int i = cInstance.callAFooIndirectly();
        System.out.println(i);
        assert 42 == i;
    }
}

2
この種の設計でこれまでに最も一般的な理由は、非パブリッククラスを使用して、パブリックAPIメソッド(インターフェースや拡張抽象クラスからのメソッドなど)の実装を提供することです。JDK自体はそのようなクラスでいっぱいです(例:java.util.Collections.SingletonSet<E>privateにありますjava.util.Collections)。
ernest_k

回答:


8

私の理解は正しいですか?

はい。

制限の少ないメンバーアクセス修飾子を使用する正当な理由は何ですか?

2つの理由:

  • 場合によっては、インターフェースを実装します。インターフェイスメソッドはpublic
  • クラスの全体的なアクセスを簡単に変更できます。たとえばpublic、パッケージプライベートクラスであっても、公開したいすべてのメソッドをマークした場合、後でクラスを公開するために必要なのはpublic、クラス宣言に追加することだけです。

最後に、従うべきベストプラクティスは何ですか?

それは意見の問題なので、スタックオーバーフローの質問や回答にはあまり適していません。あなたおよび/またはあなたのチームにとって合理的であると思われること、および/またはあなたのチームのスタイルガイドがあなたに行うように指示していることをしてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.