Apakah penggunaan pengubah akses anggota yang tidak terlalu ketat dibandingkan pengubah akses kelas?

9

Katakanlah saya memiliki kelas dengan beberapa anggota, dan anggota memiliki pengubah akses yang kurang ketat daripada kelas itu sendiri.

Contoh nyata bisa:

package apples;

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

Menurut pemahaman saya, pengubah akses kelas yang lebih ketat daripada pengubah akses anggota , akan menggantikan pengubah akses anggota yang kurang ketat . Jadi kurang membatasi anggota akses pengubah seharusnya tidak berpengaruh sama sekali.

  • Apakah pemahaman saya benar?
    • Jika tidak, apa konsekuensinya?
  • Apa yang bisa menjadi alasan yang sah untuk memiliki pengubah akses anggota yang kurang ketat?
  • Akhirnya, praktik terbaik apa yang harus diikuti?

Saya juga melakukan beberapa percobaan karena saya pikir itu mungkin memiliki konsekuensi setelah saya mulai melewati referensi fungsi, tetapi meskipun demikian pengubah akses tampaknya tidak masalah.

Situasi yang saya bangun adalah sebagai berikut:

  • apples.Bmenyediakan metode publik bla()yang mengembalikan referensi ke apples.A.foo.
  • Kemudian pizzas.Cpanggilan apples.B.blauntuk mendapatkan referensi A.foodan menyebutnya.
  • Jadi A.foo()tidak langsung terlihat C, tetapi hanya dapat diakses secara tidak langsung melaluiB.bla()

Saya mengujinya dan tidak ada bedanya apakah saya membuat pengubah akses foo() paket pribadi atau tidak.

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;
    }
}
Stefan D.
sumber
2
Alasan paling umum sejauh ini untuk jenis desain ini adalah untuk menyediakan implementasi metode API publik (seperti yang dari antarmuka atau kelas abstrak yang diperluas) menggunakan kelas non-publik. JDK itu sendiri penuh dengan kelas-kelas seperti itu (mis: java.util.Collections.SingletonSet<E>ada privatedi java.util.Collections).
ernest_k

Jawaban:

8

Apakah pemahaman saya benar?

Iya.

Apa yang bisa menjadi alasan yang sah untuk memiliki pengubah akses anggota yang kurang ketat?

Dua alasan:

  • Terkadang, Anda menerapkan antarmuka; metode antarmuka haruspublic
  • Itu membuatnya lebih mudah untuk mengubah akses keseluruhan kelas Anda. Sebagai contoh, jika Anda menandai semua metode yang Anda ingin publik public, bahkan dalam kelas paket-pribadi, maka yang harus Anda lakukan untuk membuat kelas publik adalah menambah publicdeklarasi kelas.

Akhirnya, praktik terbaik apa yang harus diikuti?

Itu masalah pendapat, jadi tidak cocok untuk pertanyaan atau jawaban Stack Overflow. Lakukan apa yang tampaknya masuk akal bagi Anda dan / atau tim Anda, dan / atau lakukan apa yang disarankan oleh panduan gaya tim Anda.

TJ Crowder
sumber