Saya telah mencari dan saya tahu perbedaan teoretisnya.
- publik - Setiap kelas / fungsi dapat mengakses metode / properti.
- protected - Hanya kelas ini dan semua subclass yang dapat mengakses metode / properti.
- pribadi - Hanya kelas ini yang dapat mengakses metode / properti. Bahkan tidak akan diwarisi.
Semua baik-baik saja dan baik, pertanyaannya adalah, apa perbedaan praktis di antara mereka? Kapan Anda akan menggunakan private
dan kapan Anda akan menggunakan protected
? Apakah ada standar atau praktik yang baik yang dapat diterima untuk hal ini?
Sampai sekarang, untuk mempertahankan konsep pewarisan dan polimorfisme, saya menggunakan public
apa pun yang harus diakses dari luar (seperti konstruktor dan fungsionalitas kelas utama), dan protected
untuk metode internal (logika, metode pembantu dll). Apakah saya di jalur yang benar?
(Perhatikan bahwa pertanyaan ini untuk saya, tetapi juga untuk referensi di masa depan karena saya belum melihat pertanyaan seperti ini SO).
oop
language-agnostic
coding-style
Hantu Madara
sumber
sumber
internal
dalam bahasa C # yang membatasi tingkat akses kelas atau anggotanya dalam majelis fisik. Padahal, saya tidak yakin tentang dukungannya atau sesuatu yang serupa dalam bahasa lain.Jawaban:
Tidak, Anda tidak berada di jalur yang benar. Aturan praktis yang baik adalah: jadikan segala sesuatu senyaman mungkin. Ini membuat kelas Anda lebih dienkapsulasi, dan memungkinkan untuk mengubah internal kelas tanpa mempengaruhi kode menggunakan kelas Anda.
Jika Anda mendesain kelas Anda agar dapat diwariskan, maka pilihlah dengan hati-hati apa yang mungkin ditimpa dan dapat diakses dari subkelas, dan buat yang terlindungi (dan final, berbicara tentang Jawa, jika Anda ingin membuatnya dapat diakses tetapi tidak dapat ditimpa). Tetapi perlu diketahui bahwa, segera setelah Anda menerima untuk memiliki subclass dari kelas Anda, dan ada bidang atau metode yang dilindungi, bidang atau metode ini adalah bagian dari API publik dari kelas tersebut, dan mungkin tidak dapat diubah kemudian tanpa melanggar subclass.
Kelas yang tidak dimaksudkan untuk diwariskan harus dibuat final (di Jawa). Anda mungkin mengendurkan beberapa aturan akses (privat ke terlindungi, final ke non-final) demi pengujian unit, tetapi kemudian mendokumentasikannya, dan memperjelas bahwa meskipun metode ini dilindungi, itu tidak seharusnya diganti.
sumber
private
vsprotected
Kapan saya ingin properti diwarisi, dan kapan tidak? Saya benar-benar tidak tahu apakah pengguna kadang-kadang di masa depan ingin mengambil kelas saya dan memperpanjangnya ...Saya perkenalkan ini dengan mengatakan saya berbicara terutama tentang akses metode di sini, dan pada tingkat yang sedikit lebih rendah, menandai kelas final, bukan akses anggota.
Kebijaksanaan lama
masuk akal di hari-hari ketika ditulis, sebelum open source mendominasi ruang perpustakaan pengembang dan VCS / dependensi mgmt. menjadi sangat kolaboratif berkat Github, Maven, dll. Saat itu ada juga uang yang dihasilkan dengan membatasi cara di mana sebuah perpustakaan dapat digunakan. Saya mungkin menghabiskan 8 atau 9 tahun pertama karir saya secara ketat mengikuti "praktik terbaik" ini.
Hari ini, saya percaya itu saran yang buruk. Kadang-kadang ada argumen yang masuk akal untuk menandai metode pribadi, atau final kelas tetapi sangat jarang, dan bahkan mungkin tidak memperbaiki apa pun.
Pernahkah kamu:
Ini adalah tiga rasionalisasi terbesar yang saya dengar untuk menandai metode pribadi secara default:
Rasionalisasi # 1: Tidak aman dan tidak ada alasan untuk mengganti metode tertentu
Saya tidak dapat menghitung berapa kali saya salah tentang apakah akan ada kebutuhan untuk mengganti metode tertentu yang saya tulis. Setelah bekerja pada beberapa lib open source populer, saya belajar dengan cara yang sulit biaya sebenarnya menandai hal-hal pribadi. Ini sering menghilangkan satu-satunya solusi praktis untuk masalah yang tidak terduga atau kasus penggunaan. Sebaliknya, saya belum pernah dalam 16+ tahun pengembangan profesional menyesal menandai metode yang dilindungi dan bukan pribadi karena alasan yang terkait dengan keselamatan API. Ketika seorang pengembang memilih untuk memperluas kelas dan mengganti metode, mereka secara sadar mengatakan "Saya tahu apa yang saya lakukan." dan demi produktivitas yang seharusnya cukup. Titik. Jika berbahaya, catat di Javadocs kelas / metode, jangan membanting pintu begitu saja.
Metode penandaan yang dilindungi secara default adalah mitigasi untuk salah satu masalah utama dalam pengembangan SW modern: kegagalan imajinasi.
Rasionalisasi # 2: Itu menjaga API publik / Javadocs bersih
Yang satu ini lebih masuk akal, dan tergantung pada audiens target, itu mungkin bahkan merupakan hal yang tepat untuk dilakukan, tetapi ada baiknya mempertimbangkan berapa biaya untuk menjaga API "bersih" sebenarnya adalah: ekstensibilitas. Untuk alasan yang disebutkan di atas, mungkin lebih masuk akal untuk menandai hal-hal yang dilindungi secara default untuk berjaga-jaga.
Rasionalisasi # 3: Perangkat lunak saya bersifat komersial dan saya perlu membatasi penggunaannya.
Ini masuk akal juga, tetapi sebagai konsumen saya akan pergi dengan pesaing yang kurang ketat (dengan asumsi tidak ada perbedaan kualitas yang signifikan) setiap saat.
Jangan pernah bilang tidak akan pernah
Saya tidak mengatakan tidak pernah menandai metode pribadi. Saya mengatakan aturan praktis yang lebih baik adalah "membuat metode terlindungi kecuali ada alasan bagus untuk tidak".
Saran ini paling cocok untuk mereka yang bekerja di perpustakaan atau proyek skala besar yang telah dipecah menjadi modul. Untuk proyek yang lebih kecil atau lebih monolitik, itu cenderung tidak terlalu berarti karena Anda tetap mengendalikan semua kode dan mudah untuk mengubah tingkat akses kode Anda jika / ketika Anda membutuhkannya. Meski begitu, saya masih akan memberikan saran yang sama :-)
sumber
Rationalization # 1
- Ketika saya menandai sesuatu sebagai terlindungi saya memilih untuk melakukannya secara eksplisit karena saya merasa bahwa perilaku ini tidak final dan mungkin merupakan kasus di mana kelas anak saya ingin menimpanya. Jika saya tidak begitu yakin maka saya ingin menjadikannya pribadi secara default. Khususnya dalam bahasa seperti C # yang membuat metode non-virtual secara default, menambahkan specifier akses yang dilindungi tidak masuk akal. Anda harus menambahkan keduanyavirtual
danprotected
kata kunci untuk membuat maksud Anda sangat jelas. Juga, orang lebih suka asosiasi daripada warisan sehinggaprotected
standar sulit untuk dipahamiBerhenti menyalahgunakan bidang pribadi !!!
Komentar di sini tampaknya sangat mendukung penggunaan bidang pribadi. Nah, kalau begitu saya punya sesuatu yang berbeda untuk dikatakan.
Apakah pada dasarnya bidang pribadi baik? Iya. Tetapi mengatakan bahwa aturan emas adalah menjadikan segalanya pribadi ketika Anda tidak yakin pasti salah ! Anda tidak akan melihat masalah sampai Anda menemukan satu. Menurut pendapat saya, Anda harus menandai bidang sebagai terlindungi jika Anda tidak yakin .
Ada dua kasus yang Anda ingin perpanjang kelas:
Tidak ada yang salah dengan bidang pribadi dalam kasus pertama. Fakta bahwa orang-orang menyalahgunakan bidang pribadi membuatnya sangat frustasi ketika Anda tahu Anda tidak dapat memodifikasi apa pun.
Pertimbangkan perpustakaan sederhana yang memodelkan mobil:
Penulis perpustakaan berpikir: tidak ada alasan pengguna perpustakaan saya perlu mengakses detail implementasi yang
assembleCar()
benar? Mari kita tandai sekrup sebagai pribadi.Ya, penulis salah. Jika Anda hanya ingin memodifikasi
assembleCar()
metode tanpa menyalin seluruh kelas ke dalam paket Anda, Anda kurang beruntung. Anda harus menulis ulangscrew
bidang Anda sendiri . Katakanlah mobil ini menggunakan selusin sekrup, dan masing-masingnya melibatkan beberapa kode inisialisasi tidakrivial dalam metode pribadi yang berbeda, dan sekrup ini semuanya ditandai pribadi. Pada titik ini, ia mulai menyedot.Ya, Anda dapat berdebat dengan saya bahwa penulis perpustakaan dapat menulis kode yang lebih baik sehingga tidak ada yang salah dengan bidang pribadi . Saya tidak berpendapat bahwa bidang pribadi adalah masalah OOP . Ini adalah masalah ketika orang menggunakannya.
Moral dari cerita ini adalah, jika Anda menulis perpustakaan, Anda tidak pernah tahu apakah pengguna Anda ingin mengakses bidang tertentu. Jika Anda tidak yakin, tandai
protected
sehingga semua orang akan lebih bahagia nanti. Setidaknya jangan menyalahgunakan bidang pribadi .Saya sangat mendukung jawaban Nick.
sumber
Saya membaca sebuah artikel beberapa waktu lalu yang berbicara tentang mengunci setiap kelas sebanyak mungkin. Jadikan semuanya final dan pribadi kecuali Anda memiliki kebutuhan mendesak untuk mengekspos beberapa data atau fungsionalitas ke dunia luar. Selalu mudah untuk memperluas ruang lingkup agar lebih diizinkan di kemudian hari, tetapi tidak sebaliknya. Pertama-tama pertimbangkan membuat sebanyak mungkin hal
final
yang akan membuat memilihprivate
danprotected
lebih mudah.Sekarang jika Anda pergi dengan kelas terakhir, maka buat semuanya pribadi kecuali ada sesuatu yang benar-benar dibutuhkan oleh dunia - buat itu publik.
Jika Anda ditinggalkan dengan kelas yang memiliki subclass (es), maka hati-hati memeriksa setiap properti dan metode. Pertama-tama pertimbangkan apakah Anda bahkan ingin mengekspos properti / metode itu ke subkelas. Jika Anda melakukannya, maka pertimbangkan apakah subclass dapat mendatangkan malapetaka pada objek Anda jika itu mengacaukan nilai properti atau implementasi metode dalam proses pengesampingan. Jika memungkinkan, dan Anda ingin melindungi properti / metode kelas Anda bahkan dari subclass (terdengar ironis, saya tahu), maka jadikan itu pribadi. Kalau tidak membuatnya terlindungi.
Penafian: Saya tidak banyak memprogram di Jawa :)
sumber
final class
di Java adalah kelas yang tidak dapat diwarisi. Afinal method
adalah non-virtual, yaitu tidak dapat ditimpa oleh subclass (metode Java adalah virtual secara default). Afinal field/parameter/variable
adalah referensi variabel yang tidak dapat diubah (dalam arti bahwa itu tidak dapat dimodifikasi setelah diinisialisasi).Kapan Anda akan menggunakan
private
dan kapan Anda akan menggunakanprotected
?Warisan Pribadi dapat dianggap Diterapkan dalam hal hubungan daripada hubungan IS-A . Sederhananya, antarmuka eksternal dari kelas yang mewarisi tidak memiliki hubungan (terlihat) dengan kelas yang diwarisi, Ia menggunakan
private
warisan hanya untuk mengimplementasikan fungsi yang serupa yang disediakan oleh kelas Base.Tidak seperti, Private Warisan, Warisan terlindungi adalah bentuk terbatas dari Warisan, di mana kelas turunan IS-A semacam kelas Base dan ia ingin membatasi akses anggota yang diturunkan hanya ke kelas turunan.
sumber
Yah itu semua tentang enkapsulasi jika kelas tagihan menangani penagihan pembayaran maka di kelas produk mengapa perlu seluruh proses proses penagihan yaitu metode pembayaran cara membayar di mana harus membayar .. jadi hanya membiarkan apa yang digunakan untuk kelas dan objek lain tidak lebih dari publik untuk mereka yang menggunakan kelas lain juga, terlindungi hanya untuk kelas yang diperluas. Seperti Anda madara uchiha pribadi seperti
"limboo"
Anda dapat melihatnya (Anda hanya kelas satu kelas).sumber