Saya sedang melalui pertanyaan ini Apakah ada cara untuk mengganti variabel kelas di Jawa? Komentar pertama dengan 36 suara positif adalah:
Jika Anda pernah melihat
protected static
, jalankan.
Adakah yang bisa menjelaskan mengapa protected static
disukai?
final
. Bidang statis yang bisa berubah yang dibagikan di seluruh kelas pasti menimbulkan kekhawatiran. Beberapa kelas yang memperbarui bidang statis sepertinya tidak dapat diandalkan atau mudah diikuti, terutama karena keberadaan bidang atau metode yang dilindungi menyiratkan bahwa kelas tersebut dimaksudkan untuk diperluas oleh kelas dalam paket lain, mungkin kelas yang tidak berada di bawah kendali penulis kelas yang berisi bidang yang dilindungi.final
bukan berarti bidang tidak dapat diubah. Anda selalu dapat memodifikasi yangobject
direferensikan olehfinal
variabel referensi.Jawaban:
Ini lebih merupakan masalah gaya daripada masalah langsung. Ini menunjukkan bahwa Anda belum memikirkan dengan baik apa yang terjadi dengan kelas.
Pikirkan tentang apa
static
artinya:Pikirkan tentang apa
protected
artinya:Kedua arti itu tidak sepenuhnya eksklusif tetapi cukup dekat.
Satu-satunya kasus yang dapat saya lihat di mana Anda dapat menggunakan keduanya bersama-sama adalah jika Anda memiliki kelas abstrak yang dirancang untuk diperpanjang dan kelas yang diperluas kemudian dapat mengubah perilaku menggunakan konstanta yang ditentukan dalam aslinya. Pengaturan semacam itu kemungkinan besar akan berakhir sangat berantakan dan menunjukkan kelemahan dalam desain kelas.
Dalam kebanyakan kasus, akan lebih baik untuk memiliki konstanta sebagai publik karena itu hanya membuat semuanya lebih bersih dan memungkinkan orang-orang untuk membuat sub-klasifikasi lebih fleksibel. Terlepas dari hal lain dalam banyak kasus, komposisi lebih disukai daripada pewarisan, sementara kelas abstrak memaksakan pewarisan.
Untuk melihat satu contoh bagaimana ini dapat merusak sesuatu dan untuk menggambarkan apa yang saya maksud dengan variabel yang tidak memiliki keberadaan independen coba kode contoh ini:
Anda akan melihat hasilnya:
Coba sendiri di: https://ideone.com/KM8u8O
Kelas
Test2
dapat mengakses anggota statistest
dariTest
tanpa perlu mengkualifikasikan nama - tetapi tidak mewarisi atau mendapatkan salinannya sendiri. Ia melihat objek yang sama persis dalam memori.sumber
Rectangle
) untuk menyesuaikan lebar / tinggi untuk memastikan kesetaraan akan (untukSquare
) akan menghasilkan hasil yang tidak diinginkan jika Anda mengganti setiap supertipe dengan instance dari subtipe itu.Ini disukai karena kontradiktif.
Membuat variabel
protected
menyiratkan itu akan digunakan dalam paket atau akan diwarisi dalam subkelas .Membuat variabel
static
menjadikannya anggota kelas, menghilangkan niat untuk mewarisinya . Ini hanya menyisakan niat untuk digunakan dalam sebuah paket , dan kami memilikipackage-private
untuk itu (tanpa pengubah).Satu-satunya situasi yang saya anggap berguna ini adalah jika Anda mendeklarasikan kelas yang harus digunakan untuk meluncurkan aplikasi (seperti JavaFX's
Application#launch
, dan hanya ingin dapat meluncurkan dari subkelas. Jika melakukannya, pastikan metodenya jugafinal
untuk disallow menyembunyikan . Tapi ini bukan "norma", dan mungkin diterapkan untuk mencegah penambahan lebih banyak kerumitan dengan menambahkan cara baru untuk meluncurkan aplikasi.Untuk melihat tingkat akses setiap pengubah, lihat ini: Tutorial Java - Mengontrol Akses ke Anggota Kelas
sumber
static
menghilangkan niat mewarisinya. Karena subclass saya di paket lain masih membutuhkan field super untuk bisaprotected
mengaksesnya, padahal itustatic
.package-private
tidak dapat membantuprotected static
. Tapi itu bau kode, karena itu bagian " lari ". Pengubah akses dan pewarisan adalah dua subjek yang berbeda. Ya, Anda tidak akan dapat mengakses anggota statis dari kelas super jika itupackage-private
. Namun Anda tidak boleh mengandalkan warisan kestatic
bidang referensi sejak awal; itu pertanda desain yang buruk. Anda akan melihat upaya menggantistatic
metode tidak memberikan hasil, yang merupakan tanda yang jelas bahwa warisan tidak berbasis kelas. Jika Anda memerlukan akses di luar kelas atau paket, itu haruspublic
private static
fungsi util pada awalnya, tetapi saya pikir seseorang mungkin ingin meningkatkan atau menyesuaikan dari kelas saya dan fungsi util ini juga dapat memberikan kemudahan bagi mereka.public
mungkin tidak sesuai karena metode util bukan untuk pengguna instance kelas saya. Bisakah Anda membantu saya menemukan desain yang bagusprotected
? Terima kasihSaya tidak melihat alasan khusus mengapa hal ini tidak disukai. Mungkin selalu ada alternatif untuk mencapai perilaku yang sama, dan itu akan tergantung pada arsitektur sebenarnya apakah alternatif ini "lebih baik" daripada metode statis yang dilindungi atau tidak. Tetapi satu contoh di mana metode statis yang dilindungi akan masuk akal, setidaknya, adalah sebagai berikut:
(Diedit untuk dipecah menjadi paket terpisah, agar penggunaan
protected
lebih jelas)Berasal dari itu:
Kelas turunan lainnya:
The
protected static
pengubah tentu dapat dibenarkan di sini:static
, karena tidak bergantung pada variabel instan. Mereka tidak dimaksudkan untuk digunakan secara langsung sebagai metode polimorfik, melainkan metode "utilitas" yang menawarkan implementasi default yang merupakan bagian dari komputasi yang lebih kompleks, dan berfungsi sebagai "blok bangunan" dari implementasi yang sebenarnya.public
, karena merupakan detail implementasi. Dan mereka tidak bisaprivate
karena mereka harus dipanggil oleh kelas tambahan. Mereka juga tidak bisa memiliki visibilitas "default", karena mereka tidak akan bisa diakses oleh kelas-kelas yang diperluas di paket lain.(EDIT: Orang dapat berasumsi bahwa komentar asli hanya mengacu pada bidang , dan bukan metode - maka, bagaimanapun, itu terlalu umum)
sumber
protected final
(karena Anda tidak ingin mereka diganti), bukanstatic
. Fakta bahwa suatu metode tidak menggunakan variabel instan tidak berarti itu harusstatic
(meskipun bisa ).final
, ini tidak hanya menjelaskan bahwa metode tersebut tidak dimaksudkan untuk diganti, tetapi juga menjelaskan kepada pembaca bahwa metode tersebut tidak menggunakan variabel instan. Singkatnya: Tidak ada alasan untuk tidak membuatnya statis.protected
, bukan untuk menunjukkan warisan, tetapi menyimpannya di bawah satu paket - tidak diekspos. Saya kira antarmuka tersegel akan membantu dengan cara ini ketika mereka melakukannya di javaprotected
berarti "Mewarisi kelas (bahkan dalam paket yang berbeda)" ...Anggota statis tidak diwariskan, dan anggota yang dilindungi hanya dapat dilihat oleh subkelas (dan tentu saja kelas yang memuatnya), jadi a
protected static
memiliki visibilitas yang sama denganstatic
, menunjukkan kesalahpahaman oleh pembuat kode.sumber
protected
tidak sama. Jika Anda hanya mengatakanstatic
, bidang ini hanya dapat dilihat oleh subclass dalam paket yang sama.protected static
memungkinkan akses di dalam paket atau dari subclass . Membuat variabel statis menghapus maksud subclassing, meninggalkan satu-satunya maksud adalah akses dari dalam paket.Sebenarnya tidak ada yang salah secara fundamental
protected static
. Jika Anda benar-benar menginginkan variabel atau metode statis yang terlihat untuk paket dan semua subclass dari kelas yang mendeklarasikan, lanjutkan dan buatprotected static
.Beberapa orang umumnya menghindari penggunaan
protected
karena berbagai alasan dan beberapa orang berpikirstatic
variabel non-final harus dihindari dengan segala cara (saya pribadi bersimpati dengan yang terakhir sampai taraf tertentu), jadi saya kira kombinasiprotected
danstatic
harus terlihat buruk ^ 2 untuk yang milik kedua kelompok.sumber
Protected digunakan sehingga bisa digunakan di subclass. Tidak ada logika dalam mendefinisikan statis yang dilindungi saat menggunakan dalam konteks kelas konkret karena Anda dapat mengakses variabel yang sama dengan cara statis. Namun pemohon akan memberikan peringatan untuk mengakses variabel statis kelas super dengan cara statis.
sumber
Nah, seperti yang sebagian besar orang jawab:
protected
berarti - ' paket-privat + visibilitas ke subkelas - properti / perilaku DIBERIKAN 'static
berarti - ' kebalikan dari instance - ini adalah properti / perilaku CLASS, yaitu TIDAK DIWARISKAN 'Oleh karena itu, mereka sedikit kontradiktif dan tidak cocok.
Namun, baru-baru ini saya menemukan kasus penggunaan di mana mungkin masuk akal untuk menggunakan keduanya secara bersamaan. Bayangkan Anda ingin membuat
abstract
kelas yang merupakan induk untuk tipe yang tidak dapat diubah dan memiliki sekumpulan properti yang sama untuk subtipe. Untuk mengimplementasikan keabadian dengan benar dan menjaga keterbacaan, seseorang mungkin memutuskan untuk menggunakan pola Builder .Dan kenapa
protected static
? Karena saya ingin subtipe non-abstrakAbstactType
yang mengimplementasikan Builder non-abstraknya sendiri dan terletak di luarpackage X
agar dapat mengakses dan menggunakan kembaliBaseBuilder
.Tentu saja kita dapat
BaseBuilder
mempublikasikannya tetapi kemudian kita sampai pada pernyataan kontradiktif lainnya:Jadi dalam kedua kasus dengan
protected static
danpublic
pembangun fileabstract class
kami menggabungkan pernyataan yang kontradiktif. Ini adalah masalah preferensi pribadi.Namun, saya masih lebih memilih
public
builderabstract class
karenaprotected static
bagi saya terasa lebih tidak wajar di dunia OOD dan OOP!sumber
Tidak ada salahnya memiliki
protected static
. Satu hal yang diabaikan oleh banyak orang adalah Anda mungkin ingin menulis kasus uji untuk metode statis yang tidak ingin Anda ungkapkan dalam keadaan normal. Saya perhatikan ini sangat berguna untuk menulis tes untuk metode statis di kelas utilitas.sumber