Enkapsulasi berarti bahwa status suatu objek hanya terjadi melalui antarmuka yang ditentukan, dan karena itu kelas dapat memastikan bahwa status ini selalu valid dan sesuai dengan tujuan kelas.
Oleh karena itu, dalam beberapa kasus, sangat sesuai dengan prinsip enkapsulasi untuk hanya mengekspos bidang secara publik - semua nilai yang mungkin untuk bidang valid dengan semua nilai yang mungkin dari semua bidang lainnya, dan oleh karena itu pemrogram dapat secara aktif memutuskan untuk mengizinkan bidang tersebut untuk dimanipulasi secara bebas oleh kode luar.
Kasus-kasus ini sebagian besar terbatas pada kelas yang sebagian besar merupakan "data lama biasa". Mereka juga tidak terlalu menarik dalam hal ini, jadi cukup tentang mereka.
Dalam kasus lain, dalam bahasa lain, seseorang akan memiliki metode pengambil dan penyetel, sesuatu seperti int getId()mendapatkan nilai dan void setId(int val)memperbaruinya.
Properti memungkinkan kita menggunakan sintaks yang sama untuk membaca dan menulis melalui metode seperti yang akan kita gunakan untuk membaca dan menulis bidang. Ini adalah gula sintaksis yang baik, meski tidak vital.
(Sebenarnya, karena cara kerja refleksi dan kasus seperti DataBinder.Evalitu dapat berguna untuk memiliki properti bahkan ketika bidang akan berfungsi dengan baik, tapi itu masalah lain).
Hingga penyetel pribadi diperkenalkan (sebenarnya, yang diubah dengan C # 2 adalah sintaksis untuk memiliki penyetel pribadi dan pengambil publik atau dilindungi di blok yang sama), kita dapat memiliki metode pribadi untuk melakukan pekerjaan penyetel pribadi, jadi setter pribadi tidak terlalu diperlukan. Mereka berguna, jadi meskipun hanya gula sintaksis, mereka cukup berguna.
Enkapsulasi bukanlah masalah apakah penyetel (atau pengambil) Anda publik, pribadi, terlindungi, atau internal, tetapi masalah apakah mereka pantas . Mulailah dengan default setiap bidang menjadi pribadi (dan dalam hal ini readonly) dan kemudian jika perlu tambahkan anggota (apakah properti atau metode) yang mengubah bidang tersebut, dan pastikan bahwa objek tetap valid saat berubah . Ini memastikan bahwa kelas ' invariant disimpan, yang berarti aturan yang mendeskripsikan set status yang valid tidak pernah rusak (konstruktor juga membantu dengan memastikannya dimulai dalam status yang valid).
Adapun pertanyaan terakhir Anda, menjadi tidak berubah berarti bahwa kelas tidak memiliki penyetel publik, dilindungi atau internal dan tidak ada metode publik, dilindungi atau internal yang mengubah bidang apa pun. Ada derajat ini, di C # ada tiga derajat yang mungkin:
Semua bidang instance kelas adalah readonly, bahkan kode pribadi tidak dapat mengubahnya. Itu dijamin tidak dapat diubah (apa pun yang mencoba mengubahnya tidak akan dikompilasi) dan kemungkinan pengoptimalan dapat dilakukan di balik ini.
Kelas tidak dapat diubah dari luar karena tidak ada anggota publik yang mengubah apa pun, tetapi tidak dijamin oleh penggunaan readonlyuntuk tidak diubah dari dalam.
Kelas tidak dapat diubah seperti yang terlihat dari luar, meskipun beberapa status berubah sebagai detail implementasi. Misal, sebuah field bisa dimoisasi, dan karena itu sementara dari luar sebuah usaha untuk mendapatkannya hanya mengambil nilai yang sama, percobaan pertama tersebut sebenarnya menghitungnya dan kemudian menyimpannya untuk diambil pada percobaan berikutnya.
private File settingsFile = null;dan kemudian di salah satu konstruktor:if (settingsFile == null) { settingsFile = GetSettingsFile() };. Refactoring code seperti itu terkadang membuat saya menangis :). Hanya karena Anda dapat menetapkan anggota sebelum konstruktor, tidak berarti Anda harus, karena, dengan banyak konstruktor, ini membuat SULIT untuk mengikuti logika. Penyetel pribadi memaksa Anda untuk menyetel nilai di dalam konstruktor atau nanti.