mencari kasus penggunaan tertentu di mana subclass dan kelas dalam paket yang sama perlu mengakses bidang atau metode yang dilindungi ...
Bagi saya, use case semacam itu agak umum daripada spesifik, dan itu berasal dari preferensi saya untuk:
- Mulailah dengan pengubah akses seketat mungkin, menggunakan yang lebih lemah hanya nanti jika dianggap perlu.
- Minta unit test berada dalam paket yang sama dengan kode yang diuji.
Dari atas, saya dapat mulai mendesain objek saya dengan pengubah akses default (saya akan mulai dengan private
tetapi itu akan mempersulit pengujian unit):
public class Example {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
void doSomething() {} // default access
}
static class Unit2 {
void doSomething() {} // default access
}
static class UnitTest {
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Catatan di potongan di atas, Unit1
, Unit2
dan UnitTest
yang bersarang dalam Example
untuk kesederhanaan presentasi, tetapi dalam proyek nyata, saya kemungkinan akan memiliki kelas-kelas dalam file terpisah (dan UnitTest
bahkan dalam direktori terpisah ).
Kemudian, ketika suatu kebutuhan muncul, saya akan melemahkan kontrol akses dari standar menjadi protected
:
public class ExampleEvolved {
public static void main(String [] args) {
new UnitTest().testDoSomething(new Unit1(), new Unit2());
}
static class Unit1 {
protected void doSomething() {} // made protected
}
static class Unit2 {
protected void doSomething() {} // made protected
}
static class UnitTest {
// ---> no changes needed although UnitTest doesn't subclass
// ...and, hey, if I'd have to subclass... which one of Unit1, Unit2?
void testDoSomething(Unit1 unit1, Unit2 unit2) {
unit1.doSomething();
unit2.doSomething();
}
}
}
Anda lihat, saya dapat menjaga kode tes unit ExampleEvolved
tidak berubah karena metode yang dilindungi dapat diakses dari paket yang sama, meskipun mengakses objek bukan sub-kelas .
Lebih sedikit perubahan yang diperlukan => modifikasi yang lebih aman; setelah semua saya mengubah hanya pengubah akses dan saya tidak memodifikasi metode Unit1.doSomething()
dan Unit2.doSomething()
melakukan apa, jadi itu wajar untuk mengharapkan kode tes unit untuk terus berjalan tanpa modifikasi.
protected
hanya subkelas? Jujur, untuk waktu yang lama, saya mendapat kesan bahwa itulah perilakuprotected
hanya kelas dan subkelas, daninternal
perpustakaan / paket-lebar. Ini juga memilikiprotected internal
yang setara dengan Javaprotected
.IMHO, ini adalah keputusan desain yang buruk di Jawa.
Hanya berspekulasi, tapi saya pikir mereka ingin tingkat akses berada dalam perkembangan yang ketat: privat - "paket" - dilindungi - publik. Mereka tidak ingin memiliki hierarki, di mana beberapa bidang akan tersedia untuk paket tetapi tidak subclass, beberapa tersedia untuk subclass tetapi tidak paket, dan beberapa keduanya.
Namun, menurut pendapat saya yang sederhana mereka seharusnya pergi ke arah lain: Mengatakan bahwa dilindungi hanya dapat dilihat oleh kelas dan subkelas, dan paket tersebut dapat dilihat oleh kelas, subkelas, dan paket.
Saya sering memiliki data di kelas yang harus dapat diakses oleh subclass, tetapi tidak untuk sisa paket. Saya sulit sekali memikirkan kasus di mana kebalikannya benar. Saya memiliki beberapa kesempatan langka di mana saya memiliki bundel kelas yang saling terkait yang perlu berbagi data tetapi yang harus menjaga data tersebut aman dari luar bundel. Jadi oke, letakkan di paket, dll. Tapi saya tidak pernah punya kasus di mana saya ingin paket untuk berbagi data, tapi saya ingin menyimpannya dari sub-kelas. Oke, saya bisa membayangkan situasi akan datang. Saya kira jika paket ini adalah bagian dari perpustakaan yang mungkin diperluas oleh kelas yang saya tidak tahu, karena banyak alasan yang sama saya akan membuat data di kelas pribadi. Tetapi jauh lebih umum jika ingin menyediakan data hanya untuk kelas dan anak-anaknya.
Ada banyak hal yang saya rahasiakan antara saya dan anak-anak saya dan kami tidak berbagi dengan tetangga. Sangat sedikit yang saya rahasiakan antara saya dan tetangga dan tidak berbagi dengan anak-anak saya. :-)
sumber
Contoh yang baik yang langsung terlintas dalam pikiran adalah kelas utilitas yang banyak digunakan dalam paket tetapi Anda tidak ingin akses publik (di belakang layar-gambar-memuat-dari-disk, kelas menangani-penciptaan / penghancuran, dll .) bukannya membuat segalanya [Jawa setara
friend access modifier or idiom
diC++
] setiap kelas yang lain semuanya tersedia secara otomatis.sumber
Kasing penggunaan untuk pengubah akses paket / dilindungi mirip dengan yang untuk pengubah akses teman di C ++.
Satu kasus penggunaan adalah ketika menerapkan pola Memento .
Objek kenang-kenangan perlu mengakses keadaan internal suatu objek, untuk menahannya, untuk berfungsi sebagai pos pemeriksaan untuk membatalkan operasi.
Mendeklarasikan kelas dalam paket yang sama adalah salah satu cara yang mungkin untuk mencapai pola Memento, karena Java tidak memiliki pengubah akses "teman" .
sumber
simetri?
Jarang membutuhkan akses seperti itu, itulah sebabnya akses standar jarang digunakan. Tetapi kadang-kadang kerangka kerja menginginkannya untuk kode yang dihasilkan, di mana kelas pembungkus ditempatkan dalam paket yang sama yang berinteraksi dengan kelas Anda secara langsung, pergi ke anggota, bukan pengakses untuk alasan kinerja .. Pikirkan GWT.
sumber
Hirarki enkapsulasi Java didefinisikan dengan baik:
Kelas -> Paket -> Warisan
"Dilindungi" hanyalah bentuk privasi yang lebih lemah daripada paket-default seperti yang ditentukan oleh desainer Java. Akses ke item bawaan-paket terbatas pada subset entitas yang diizinkan untuk mengakses item yang dilindungi.
Masuk akal dari sudut pandang matematika dan implementasi untuk memiliki set entitas Anda yang diizinkan mengakses hal-hal yang akan disarangkan. (Anda tidak dapat menyarangkan set akses-paket Anda di dalam set akses-terlindungi Anda karena kelas diizinkan mewarisi dari paket lain).
Masuk akal dari sudut pandang konseptual untuk memiliki sesuatu di java.util untuk menjadi "lebih ramah" dengan kelas lain dalam paket daripada sesuatu di com.example.foo.bar yang mensubklasifikasikan. Dalam kasus sebelumnya, kelas-kelas cenderung ditulis oleh penulis yang sama, atau setidaknya coders dari organisasi yang sama.
sumber