Saya baru mengenal pemrograman berorientasi objek, dan satu konsep yang telah lama saya pahami adalah kekekalan. Saya pikir bola lampu padam tadi malam tapi saya ingin memverifikasi:
Ketika saya menemukan pernyataan bahwa objek tidak dapat diubah tidak dapat diubah, saya bingung karena saya dapat, misalnya, melakukan hal berikut:
NSString *myName = @"Bob";
myName = @"Mike";
Di sana, saya baru saja mengubah myName, dari tipe NSString yang tidak dapat diubah. Masalah saya adalah bahwa kata, "objek" dapat merujuk ke objek fisik dalam memori, atau abstraksi, "myName." Definisi sebelumnya berlaku untuk konsep kekekalan.
Sedangkan untuk variabel, definisi imutabilitas yang lebih jelas (bagi saya) adalah bahwa nilai objek yang tidak dapat diubah hanya dapat diubah dengan juga mengubah lokasinya dalam memori, yaitu referensi (juga dikenal sebagai penunjuknya).
Apakah ini benar, atau apakah saya masih tersesat di hutan?
sumber
NSString
, itu " penunjuk ke danNSString
", yang tidak dapat diubah. Aku tahu apa-apa tentang C objektif, tapi aku menebak dalam contoh Anda yang@"Mike"
menciptakan contoh baru dariNSString
dan menugaskan ke pointer ,myName
. Jadi Anda belum mengubah objek yangmyName
menunjuk, hanya apa yang menunjuk.Jawaban:
Sepertinya Anda sedang menuju ke arah yang benar, tetapi belum mendapatkannya. Ini salah:
Dalam cuplikan kode Anda,
myName
bukan dari tipe yang tidak dapat diubahNSString
, itu adalah tipe yang dapat berubahNSString*
(pointer ke NSString). Kedengarannya seperti hal utama yang Anda lewatkan adalah untuk memahami bahwa pointer hanyalah nilai lain , dan memiliki kehidupan yang benar-benar terpisah dari hal yang ditunjuknya (atau benda, jika Anda mengubahnya sebagian jalan selama masa pakainya).Kamu bilang:
Ini salah. Objek tidak memiliki pointer yang menunjuk ke sana, juga tidak ada lokasi memori objek yang dikendalikan atau dipengaruhi oleh pointer ke sana.
Jadi, dua
NSString
objek dalam contoh Anda (@"Bob"
dan@"Mike"
) benar-benar terpisah darimyName
variabel. Mereka juga benar-benar terpisah satu sama lain. Ketika Anda mengubahmyName
ke menunjuk ke@"Mike"
bukannya menunjuk ke@"Bob"
, Anda tidak mengubahNSString
objek.Untuk kelengkapan, saya akan perhatikan bahwa pemulung membuat ini lebih rumit karena perubahan pada pointer dapat mempengaruhi objek yang mereka tuju (ed). Namun, ini adalah detail implementasi yang seharusnya tidak mempengaruhi perilaku kode yang dapat diamati.
sumber
Anda tersesat pada kata-kata. Kekekalan berarti: Selama Anda tidak mengubah variabel, itu akan selalu "mengandung" nilai yang sama, tidak peduli apa yang Anda lakukan dengan variabel lain.
Contoh balik dalam C (sedikit disederhanakan, dengan asumsi arsitektur yang memungkinkan itu):
Sekarang tidak lagi "berisi" (yaitu menunjuk pada) string "Hello World", tapi itu "Yello World" sebagai gantinya.
Dalam bahasa di mana string tidak dapat diubah, seperti Java dan (EDIT: aman) C #, Anda tidak bisa melakukan itu. Tidak mungkin. Ini berarti bahwa setiap bagian dari program dapat dengan aman menyimpan referensi ke string dan mengandalkan bahwa isinya tidak pernah berubah; jika tidak, mereka harus membuat salinan hanya agar aman.
Tetapi variabel masih bisa berubah. Anda bisa membiarkannya menunjuk ke objek lain. Hanya saja benda itu sendiri tidak akan berubah di belakang Anda.
sumber
unsafe
kode.Anda membingungkan variabel dengan objek. Variabel dapat digunakan untuk menyimpan referensi ke objek, tetapi mereka BUKAN objek. Ini adalah objek yang tidak berubah, bukan variabel, jadi Anda bisa mengubah variabel dari satu objek ke objek lain, tetapi Anda tidak bisa mengubah atribut objek jika tidak berubah.
Pikirkan benda itu sebagai tetangga yang keras dan mabuk. Jika dia masuk akal (bisa berubah), Anda mungkin bisa mengetuk pintunya dan mengubahnya menjadi gaya hidup di mana dia tidak membuat banyak kebisingan. Tetapi jika ia tidak berubah, satu-satunya perubahan Anda adalah berharap bahwa orang lain masuk!
sumber
Variabel bukan objek. Variabel adalah nama, yang merujuk ke objek (atau lebih umum suatu nilai).
Misalnya "penjaga gawang" adalah nama yang kami gunakan untuk merujuk ke objek (orang) yang bertanggung jawab untuk mempertahankan tujuan. Tetapi jika saya mengganti orang itu dengan orang lain (karena mantan terluka atau yang lainnya), orang baru sekarang disebut sebagai "penjaga gawang".
Pernyataan penugasan adalah apa yang membuat variabel dapat berubah (beberapa bahasa, seperti Haskell tidak memilikinya dan pada kenyataannya menggunakan variabel yang tidak dapat diubah). Ini memungkinkan Anda untuk mendefinisikan kembali makna nama dan dengan demikian menetapkan kembali nilainya.
Sekarang benda itu sendiri tidak bisa berubah. Beberapa ribu tahun yang lalu orang bisa menganggap berlian tidak berubah. Apa pun yang Anda lakukan dengan berlian, Anda tidak dapat memodifikasinya. Apakah Anda menyebutnya waggawooga (secara longgar diterjemahkan menjadi "batu mengkilap terbesar suku kami") atau berhenti menyebutnya seperti itu (karena Anda menemukan yang lebih besar), intan tetap sama. Sebaliknya potongan kayu yang Anda gunakan untuk mengukir dalam gambar lucu dengan waggawooga Anda tidak tetap sama. Itu terbukti bisa berubah. Bahkan jika itu memiliki nama yang sama sepanjang waktu.
Baik variabel dan nilai-nilai dapat berubah (secara independen). Dalam hal ini, objeklah yang tidak bisa diubah. Setelah membuat
NSString
, Anda tidak dapat memodifikasinya. Anda bisa menyebutnya nama dan menyebarkannya, tetapi tetap sama. Berbeda dengan itu,NSMutableString
dapat diubah setelah pembuatan, misalnya dengan memanggilsetString
metode.sumber
Saya pikir Anda merasa bingung, karena Anda mencampurkan dua konsep: objek itu sendiri dan nama variabel terikat ke objek itu.
Objek yang tidak dapat diubah tidak dapat diubah. Titik. Namun, nama variabel (simbol) terikat ke objek yang tidak dapat diubah, dapat dimodifikasi untuk terikat ke objek lain yang tidak dapat diubah.
Dengan kata lain, apa yang Anda lakukan dalam dua baris ini adalah:
myName
ke objek itumyName
ke objek itusumber
Jenis Anda Anda bukan
NSString
, itu adalah " pointer ke sebuahNSString
", yang tidak berubah. Saya tidak tahu apa-apa tentang tujuan C, tapi saya menduga dalam contoh Anda yang@"Mike"
membuat contoh baruNSString
dan menugaskannya ke pointermyName
. Jadi Anda tidak berubah objek yangmyName
sedang menunjuk ke, hanya apa itu menunjuk.sumber
Berikut adalah contoh objek yang bisa berubah: array
char
dalam C:Aku dapat mengubah isi dari
str
untuk isi hati saya (selama itu tidak lebih dari 10 karakter). Agar dapat dikenali sebagai string oleh fungsi pustaka string C, harus ada trailing 0, sehingga dapat menyimpan string hingga 9 karakter:und jadi weiter .
Bandingkan ini dengan objek string di Jawa:
String contoh (bongkahan memori yang berisi karakter 'H', 'e', 'l', 'l', dan 'o') tidak dapat dimodifikasi; Saya tidak dapat mengubah konten string itu. Ketika Anda menulis sesuatu seperti
Anda tidak menambahkan "Dunia" ke akhir instance "Halo"; Anda membuat instance baru , menyalin "Hello World" ke sana, dan memperbarui
foo
untuk merujuk ke instance string baru itu.foo
tidak sendiri berisi instance string; itu hanya merujuk ke instance itu (mirip dengan pointer di C atau Obj-C), maka mengapa tipe seperti String disebut tipe referensi.sumber