Saya berasal dari latar belakang C ++ dan saya akan keluar C # dalam pekerjaan saya saat ini dan saya baru saja membaca banyak T&J tentang apa perbedaan antara bidang publik dan properti dan semua bolak-balik dalam variasi dan inkarnasi dari ini pertanyaan dasar (mis. posting SO ini dan semua pertanyaan terkait lainnya ). Semua pertanyaan tersebut dibahas dalam hal perbedaan praktis yang menerima begitu saja keberadaan sistem properti, tetapi saya pikir akan lebih baik untuk mendekati subjek ini dalam hal apa perancang semua bahasa yang memutuskan untuk mendukung properti pada awalnya. Tempat berpikir (lihat daftar di artikel Wikipedia di sini). Bagaimana OOP berkembang dari C ++ / Java untuk memperluas ke apa yang artikel Wikipedia dengan menarik mengidentifikasi sebagai jalan tengah antara metode dan data anggota:
"Yaitu, properti adalah perantara antara kode anggota (metode) dan data anggota (variabel instan) dari kelas, dan properti menyediakan tingkat enkapsulasi yang lebih tinggi daripada bidang publik."
MSDN menambahkan latar belakang lebih lanjut:
"Meskipun properti secara teknis sangat mirip dengan metode, mereka sangat berbeda dalam hal skenario penggunaannya. Mereka harus dilihat sebagai bidang cerdas. Mereka memiliki sintaks panggilan bidang, dan fleksibilitas metode."
Saya ingin tahu bagaimana sampai pada tingkat enkapsulasi tingkat menengah ini terbukti bermanfaat untuk pemrograman secara umum. Saya berasumsi konsep ini tidak hadir pada inkarnasi pertama bahasa pemrograman yang mengekspresikan paradigma OOP.
BMI = bob.weight/sq(bob.height)
berbunyi lebih baik tanpa()
IMO.Jawaban:
Ini semua tentang Enkapsulasi dan Prinsip Akses Seragam.
Objek harus dapat menanggapi pesan dengan mengembalikan data yang ada atau menjalankan metode, tetapi pengirim tidak dapat mengetahui yang mana. Atau jika Anda melihat ini dari sisi pengirim: pengirim harus dapat mengakses data yang ada atau menjalankan metode melalui antarmuka yang seragam.
Ada beberapa cara untuk mencapai ini:
singkirkan data sama sekali, cukup metode (Newspeak melakukan ini)
singkirkan metode sama sekali, hanya punya data (Self melakukan ini, "metode" hanyalah
Method
objek yang ditugaskan ke variabel instan, variabel instan dilihat dengan pengiriman virtual)tidak membuat perbedaan sintaksis atau semantik antara metode dan data (Scala melakukan ini, mengakses suatu bidang secara sintaktis tidak dapat dibedakan dari memanggil metode tanpa daftar argumen (
foo.bar
), menugaskan ke suatu bidang secara sintaktis tidak dapat dibedakan dari memanggil metode yang dinamai secara khusus (foo.bar = baz
) adalah sama sepertifoo.bar_=(baz)
memanggil metode yang dinamaifoo_=
, dan nilai read-only dapat diganti atau diimplementasikan oleh metode tanpa daftar parameter (yaituval foo
) dalam superclass dapat diganti (atauabstract
val
diimplementasikan) dalam subkelas dengan metodedef foo
)Java, bagaimanapun, tidak mengikuti Prinsip Akses Seragam. Di Jawa, dimungkinkan untuk membedakan antara mengakses data dan menjalankan metode.
foo.bar
berbeda darifoo.bar()
. Alasan untuk ini adalah bahwa bidang dan metode berbeda secara semantik dan sintaksis.C # mencoba untuk memperbaikinya dengan menambahkan properti ke bahasa, pada dasarnya metode yang terlihat seperti bidang. Namun, panggilan metode masih terlihat dan terasa berbeda dari akses bidang dan properti. Bidang dan properti sekarang memiliki Akses Seragam, tetapi metode tetap tidak.
Jadi, ini sebenarnya tidak memperbaiki masalah: Anda tidak dapat memperbaiki memiliki dua cara berbeda untuk mengakses sesuatu dengan menambahkan cara ketiga untuk mengakses sesuatu! Bahkan jika cara ketiga itu terlihat seperti salah satu dari dua cara lainnya, Anda masih akan memiliki (setidaknya) dua cara yang berbeda. Anda hanya dapat memperbaikinya dengan menyingkirkan semua cara yang berbeda kecuali satu atau menyingkirkan perbedaan.
Tidak masalah memiliki bahasa dengan metode, properti, dan bidang, tetapi ketiganya harus memiliki akses yang seragam.
sumber
Yah, saya tidak 100% yakin, tapi saya kira segalanya mungkin lebih sederhana dari yang Anda harapkan. Dari sekolah pemodelan OO tahun 90-an, ada permintaan untuk kelas pemodelan dengan atribut anggota yang dienkapsulasi, dan ketika diimplementasikan dalam bahasa seperti C ++ atau Java, ini biasanya mengarah ke kode dengan banyak getter dan setter, sehingga banyak "noise" kode untuk persyaratan yang relatif sederhana. Perhatikan bahwa sebagian besar (mungkin semua, tidak memeriksa ini) bahasa yang tercantum dalam artikel Wikipedia Anda yang terhubung mulai memperkenalkan "properti" objek pada akhir 90-an atau lebih baru.
Saya kira itu adalah alasan utama perancang bahasa memutuskan untuk menambahkan beberapa gula sintaksis untuk mengurangi kebisingan itu. Dan meskipun properti pasti bukan "konsep inti OO", mereka setidaknya ada hubungannya dengan orientasi objek. Mereka tidak menunjukkan "evolusi OOP" (seperti yang diasumsikan oleh judul pertanyaan Anda), tetapi mereka mendukung pemodelan OO di tingkat bahasa pemrograman untuk membuat implementasi lebih mudah.
sumber
Anda memilikinya mundur (semacam). Lambda Calculus hadir sebagai dasar formal inti untuk bahasa pemrograman, dan telah berlangsung selama beberapa dekade. Tidak memiliki bidang.
Untuk memodelkan keadaan yang bisa berubah, Anda perlu membuat dua abstraksi. Satu mewakili pengaturan beberapa negara, dan yang lain mengambil keadaan itu (Bab 13 dalam versi TaPL saya untuk referensi). Terdengar akrab? Dari latar belakang teoritis , OO tidak berevolusi untuk memiliki barang-barang ini. OO membaca Bahasa Pemrograman 101 dan membuat bayi melangkah maju.
Dari perspektif praktis , ada dua motivasi yang cukup jelas. Anda berasal dari latar belakang C ++, jadi apa yang perlu terjadi jika Anda memiliki bidang publik - katakanlah ... teks dalam kotak teks. Apa yang terjadi ketika Anda ingin mengubah desain Anda sehingga "setiap kali kotak teks ini berubah, lakukan bla"? Anda bisa mematikan bidang itu, membuat satu atau dua fungsi dan memasang logika itu, karena Anda tidak dapat mempercayai pengembang untuk memanggil "UpdateTextbox" sendiri. Ini adalah perubahan yang sangat melanggar untuk api Anda (dan sayangnya masih merupakan perubahan besar dalam implementasi properti .NET). Perilaku semacam ini ada di semua tempat di API Windows. Karena itu masalah besar di Microsoft, C # sepertinya ingin membuatnya lebih tidak menyakitkan.
Motivasi besar lainnya adalah Kacang Jawa dan kerabat mereka. Sejumlah kerangka kerja dibangun untuk menggunakan refleksi Jawa untuk mencari
GetX
danSetX
memasangkan dan secara efektif memperlakukannya seperti properti modern. Tetapi karena mereka bukan konstruksi bahasa yang sebenarnya, kerangka kerja ini rapuh dan tidak berat. Jika Anda mengetik nama, hal-hal hanya akan pecah secara diam-diam. Jika ada yang refactored, tidak ada yang memindahkan sisi lain dari properti. Dan melakukan semua bidang / dapatkan / set boilerplate adalah verbose dan membosankan (bahkan untuk Java!). Karena C # sebagian besar dikembangkan sebagai "Jawa dengan pelajaran yang dipetik", rasa sakit semacam itu adalah salah satu pelajaran itu.Tetapi hal terbesar adalah bahwa konsep properti telah berhasil. Mudah dimengerti, mudah digunakan. Ini sangat membantu adopsi, dan sebagai alat , programmer telah menemukan bahwa properti memecahkan subset masalah lebih bersih daripada fungsi atau bidang.
sumber
Dalam .net khusus, properti berasal dari hari-hari Visual Basic lama yang seperti itu tidak berorientasi objek seperti yang kita pikirkan hari ini. Itu sebagian besar dibangun di sekitar sistem COM baru yang secara dangkal memperlakukan segala sesuatu tidak harus sebagai kelas tetapi dalam hal komponen yang akan mengekspos properti yang dapat diakses baik dalam kode tetapi juga dalam editor grafis. Ketika VB dan C # yang baru dibuat digabungkan ke .net, VB memperoleh banyak fitur OOP dan mereka menyimpan properti karena menghapusnya akan seperti langkah mundur - bayangkan jika alat pembaruan kode otomatis yang mereka miliki di Visual Studio telah mengganti semua properti Anda dengan getter dan setter dan melanggar kompatibilitas dengan semua perpustakaan-COM. Akan logis untuk mendukung mereka semua.
sumber
Properti tidak ada hubungannya dengan pemrograman berorientasi objek, karena sifat hanya gula sintaksis. Properti terlihat seperti bidang secara dangkal, dan di dunia .net, disarankan bahwa mereka berperilaku seperti bidang dalam beberapa hal, tetapi mereka bukan bidang dalam arti apa pun. Properti adalah gula sintaksis untuk satu atau dua metode: satu untuk mendapatkan nilai, dan satu untuk menetapkan nilai. Metode set atau metode get mungkin dihilangkan, tetapi tidak keduanya. Mungkin tidak ada bidang yang menyimpan nilai yang dikembalikan oleh metode get. Karena mereka berbagi sintaks dengan bidang, dan karena mereka sering menggunakan bidang, orang mengaitkan properti dengan bidang.
Properti memiliki keunggulan dibandingkan bidang:
Karena properti adalah abstraksi bidang, dan untuk kenyamanan sintaksis, bahasa seperti C # mengadopsi sintaks bidang untuk properti.
sumber
Ini masalah implementasi versus implikasi . Properti berada di OOP sebelum C ++ atau Java mengenai tempat kejadian (mereka ada di sana, dengan beberapa kekasaran di sekitar, di Simula, dan mereka mendasar bagi Smalltalk). Entitas dengan properti secara konseptual berbeda dari nilai dengan kode yang dilampirkan. Awalan get & set dalam beberapa konvensi bahasa hanya berfungsi untuk memperkeruh perairan; mereka membuat Anda mengetahui perbedaan antara bidang dan properti, dengan asumsi bahwa bidang dapat diakses secara langsung tanpa mendapatkan / mengatur dengan cara yang idiomatis untuk bahasa, dan itu bocor.
Inti dari OOP adalah untuk memperlakukan hal-hal seolah-olah mereka adalah entitas di dunia "nyata", bukan hanya sebagai struct dengan beberapa kode yang bercampur. Pemrogram lain harus tahu, sangat sedikit tentang cara saya telah mengimplementasikan sesuatu, dan sama sekali tidak harus peduli dengan mana dari berbagai nilai yang mereka boleh dapatkan dan / atau atur adalah nyata dan mana yang virtual. Jika Anda menemukan vektor saya, Anda tidak perlu tahu apakah saya menyimpan sudut dan besarnya atau komponen nyata dan imajiner internal ke objek vektor. Jika saya mengubah representasi di V2.0 perpustakaan saya, itu tidak akan memengaruhi kode Anda sama sekali (meskipun Anda mungkin ingin memanfaatkan fitur-fitur baru yang keren). Demikian pula, ada properti yang mungkin dimiliki entitas yang bergantung pada data eksternal entitas, tetapi yang tidak diragukan lagi sifat dari sudut pandang leksikal. Anda bertanya kepada orang-orang "berapa umur Anda", bukan "tolong lakukan perhitungan yang akan mengungkapkan usia Anda kepada saya", meskipun Anda tahu bahwa data yang tersedia untuk "objek" itu adalah tanggal lahir (anggota tidak berubah pribadi) dan hari ini date (properti publik yang bertambah secara otomatis, bergantung pada zona waktu, waktu musim panas, dan Garis Tanggal Internasional). Umur adalah properti, bukan metode, meskipun dibutuhkan beberapa perhitungan untuk sampai ke sana dan tidak dapat (kecuali dalam representasi komputer mainan hal-hal dengan masa hidup yang terbatas secara artifisial) disimpan sebagai bidang. walaupun Anda tahu bahwa data yang tersedia untuk "objek" itu adalah tanggal lahir (anggota tidak berubah pribadi) dan tanggal hari ini (properti publik, properti lingkungan yang bertambah otomatis, bergantung pada zona waktu, waktu musim panas, dan Garis Tanggal Internasional ). Umur adalah properti, bukan metode, meskipun dibutuhkan beberapa perhitungan untuk sampai ke sana dan tidak dapat (kecuali dalam representasi komputer mainan hal-hal dengan masa hidup yang terbatas secara artifisial) disimpan sebagai bidang. walaupun Anda tahu bahwa data yang tersedia untuk "objek" itu adalah tanggal lahir (anggota tidak berubah pribadi) dan tanggal hari ini (properti publik, properti lingkungan yang bertambah otomatis, bergantung pada zona waktu, waktu musim panas, dan Garis Tanggal Internasional ). Umur adalah properti, bukan metode, meskipun dibutuhkan beberapa perhitungan untuk sampai ke sana dan tidak dapat (kecuali dalam representasi komputer mainan hal-hal dengan masa hidup yang terbatas secara artifisial) disimpan sebagai bidang.
Daripada memikirkan properti sebagai anak haram bidang dan metode, itu jauh lebih memuaskan untuk hal metode sebagai jenis properti khusus - hal-hal yang entitas Anda dapat lakukan daripada hal-hal yang mereka lakukan. Kalau tidak, Anda tidak berurusan dengan objek / entitas secara konseptual, Anda berhadapan dengan koleksi data yang memiliki kode yang melekat padanya. The implementaions mungkin identik, tetapi implikasi yang berbeda.
Seharusnya tidak perlu dikatakan, bahwa abstraksi ini harus dibayar mahal. Jika seorang programmer yang menggunakan kelas tidak dapat mengetahui apakah ia mengakses data seperti yang disimpan atau mendapatkan / menetapkan nilai-nilai yang perlu dihitung, maka akan ada tingkat di mana bahasa juga tentu tidak pasti (dan karena itu dapat mensyaratkan bahwa semuanya memerlukan kode untuk perantara antara accessors / penyeleksi dan nilai-nilai). Tidak ada yang salah secara konsep dengan "structs with code" - mereka pasti bisa jauh lebih efisien - tetapi mereka membocorkan implementasi di semua tempat, dan itulah salah satu hal yang seharusnya dihilangkan OOP.
sumber
Sama sekali tidak ada. Properti dan OOP tidak ada hubungannya satu sama lain. Properti tidak lebih dari gula sintaksis untuk pemanggilan fungsi, dan oleh karena itu memiliki keterikatan OOP yang persis sama dengan pemanggilan fungsi — artinya, tidak ada.
Ngomong-ngomong Wikipedia benar-benar salah. Pola getMember / setMember yang Anda lihat di Java menawarkan keuntungan (dan kerugian) yang persis sama dengan properti di C #. Dan Anda dapat meniru pola ini bahkan dalam C jika Anda mau.
Properti dalam C # tidak lebih dari sintaksis yang didukung bahasa.
sumber