Sebelum saya membaca artikel ini , saya pikir kontrol akses di Ruby berfungsi seperti ini:
public
- dapat diakses oleh objek apa pun (misalnyaObj.new.public_method
)protected
- hanya dapat diakses dari dalam objek itu sendiri, dan juga setiap subclassprivate
- sama seperti dilindungi, tetapi metode ini tidak ada di subkelas
Namun, tampaknya itu protected
dan private
bertindak sama, kecuali untuk kenyataan bahwa Anda tidak dapat memanggil private
metode dengan penerima eksplisit (yaitu self.protected_method
berfungsi, tetapi self.private_method
tidak).
Apa gunanya ini? Kapan ada skenario ketika Anda tidak ingin metode Anda dipanggil dengan penerima eksplisit?
ruby
language-design
access-specifier
Kyle Slattery
sumber
sumber
Object
diizinkan untuk memanggil metode pribadi dari setiap instance lainnyaObject
, akan mungkin untuk mengatakan hal-hal seperti5.puts("hello world")
.Jawaban:
protected
metode dapat dipanggil dengan instance kelas yang mendefinisikan atau subkelasnya.private
metode hanya dapat dipanggil dari dalam objek panggilan. Anda tidak dapat mengakses metode pribadi instance lain secara langsung.Berikut adalah contoh praktis cepat:
some_method
tidak bisa diprivate
sini. Itu pastiprotected
karena Anda membutuhkannya untuk mendukung penerima eksplisit. Metode pembantu internal Anda biasanya dapatprivate
karena mereka tidak perlu dipanggil seperti ini.Penting untuk dicatat bahwa ini berbeda dari cara kerja Java atau C ++.
private
di Ruby mirip denganprotected
di Java / C ++ di mana subclass memiliki akses ke metode. Di Ruby, tidak ada cara untuk membatasi akses ke metode dari subkelasnya seperti yang Anda dapat denganprivate
di Java.Visibilitas di Ruby sebagian besar merupakan "rekomendasi" karena Anda selalu dapat memperoleh akses ke metode menggunakan
send
:sumber
private
vsprotected
harus melakukan apakah subclass dapat mewarisi metode, tetapi sebenarnya tentang dari mana metode tersebut dapat dipanggil. Terima kasih!send
?Perbedaan
self
. Bahkan Anda tidak dapat meneleponself.some_private_method
; Anda harus meneleponprivate_method
denganself
tersirat.self
penerima dapat eksplisit,self.some_private_method
diizinkan. (Penerima eksplisit lainnya masih dianulir, bahkan jika nilai runtime sama denganself
.)Di Ruby, perbedaan ini hanya saran dari satu programmer ke yang lain. Metode non-publik adalah cara untuk mengatakan "Saya berhak untuk mengubah ini; jangan bergantung padanya." Tetapi Anda masih mendapatkan gunting tajam
send
dan dapat memanggil metode apa pun yang Anda suka.Tutorial singkat
Kemudian Anda dapat menjalankan
ruby dwarf.rb
dan melakukan ini:sumber
age=
, Anda dapat (dan harus) memanggilnyaself
untuk memisahkannya dari variabel lokal.gimli.greet
,gimli
bukan penelepon, tetapi penerima. Penelepon adalah "lingkungan eksekusi tingkat atas", yang sebenarnya merupakan instance dari ad-hocObject
. Coba ini:ruby -e 'p self; p self.class'
Metode pribadi di Ruby:
Jika suatu metode bersifat pribadi di Ruby, maka itu tidak dapat dipanggil oleh penerima eksplisit (objek). Itu hanya dapat dipanggil secara implisit. Ini dapat disebut secara implisit oleh kelas di mana ia telah dijelaskan dalam serta oleh subkelas dari kelas ini.
Contoh-contoh berikut akan menggambarkannya dengan lebih baik:
1) Kelas Hewan dengan metode private class_name
Pada kasus ini:
2) Subkelas Hewan bernama Amfibi:
Pada kasus ini:
Seperti yang Anda lihat, metode pribadi hanya bisa disebut secara implisit. Mereka tidak dapat dipanggil oleh penerima eksplisit. Untuk alasan yang sama, metode pribadi tidak dapat dipanggil di luar hierarki kelas yang menentukan.
Metode yang Dilindungi di Ruby:
Jika suatu metode dilindungi dalam Ruby, maka ia dapat dipanggil secara implisit oleh kelas yang mendefinisikan dan subkelasnya. Selain itu mereka juga dapat dipanggil oleh penerima eksplisit selama penerima adalah diri atau kelas yang sama dengan diri:
1) Kelas Hewan dengan metode yang dilindungi protect_me
Pada kasus ini:
2) Kelas mamalia yang diwarisi dari kelas hewan
Pada kasus ini
3) Kelas amfibi yang diwarisi dari kelas Hewan (sama dengan kelas mamalia)
Pada kasus ini
4) Kelas yang disebut Tree
Pada kasus ini:
sumber
Pertimbangkan metode pribadi di Jawa. Itu bisa dipanggil dari dalam kelas yang sama, tentu saja, tetapi juga bisa dipanggil dengan instance lain dari kelas yang sama:
Jadi - jika penelepon adalah contoh berbeda dari kelas saya yang sama - metode pribadi saya sebenarnya dapat diakses dari "luar", jadi untuk berbicara. Ini sebenarnya membuatnya tampak tidak terlalu pribadi.
Di Ruby, di sisi lain, metode pribadi benar-benar dimaksudkan untuk menjadi pribadi hanya untuk instance saat ini. Inilah yang menghapus opsi dari penerima eksplisit.
Di sisi lain, saya tentu harus menunjukkan bahwa itu cukup umum di komunitas Ruby untuk tidak menggunakan kontrol visibilitas ini sama sekali, mengingat bahwa Ruby memberi Anda cara untuk mengatasinya. Tidak seperti di dunia Java, kecenderungannya adalah membuat segala sesuatu dapat diakses dan memercayai pengembang lain untuk tidak mengacaukan segalanya.
sumber
Bagian dari alasan mengapa metode pribadi dapat diakses oleh subclass di Ruby adalah bahwa pewarisan Ruby dengan kelas lebih tipis daripada Modul termasuk - di Ruby, kelas, pada kenyataannya, adalah sejenis modul yang menyediakan warisan, dll.
http://ruby-doc.org/core-2.0.0/Class.html
Apa artinya ini adalah bahwa pada dasarnya sebuah subclass "termasuk" kelas induk sehingga secara efektif fungsi-fungsi kelas induk, termasuk fungsi-fungsi pribadi , didefinisikan dalam subkelas juga.
Dalam bahasa pemrograman lain, memanggil metode melibatkan meleburkan nama metode ke hierarki kelas induk dan menemukan kelas induk pertama yang merespons metode tersebut. Sebaliknya, di Ruby, sementara hierarki kelas induk masih ada, metode kelas induk langsung dimasukkan ke dalam daftar metode subkelas yang telah ditentukan.
sumber
Perbandingan kontrol akses Java terhadap Ruby: Jika metode dinyatakan pribadi di Jawa, itu hanya dapat diakses oleh metode lain dalam kelas yang sama. Jika suatu metode dinyatakan terlindungi, ia dapat diakses oleh kelas-kelas lain yang ada dalam paket yang sama dan juga oleh subkelas kelas dalam paket yang berbeda. Ketika suatu metode bersifat publik, itu dapat dilihat oleh semua orang. Di Jawa, konsep visibilitas kontrol akses tergantung pada di mana kelas-kelas ini terletak pada hierarki warisan / paket.
Sedangkan di Ruby, hierarki warisan atau paket / modul tidak cocok. Ini semua tentang objek mana yang merupakan penerima suatu metode.
Untuk metode pribadi di Ruby, itu tidak pernah bisa dipanggil dengan penerima eksplisit. Kami dapat (hanya) memanggil metode pribadi dengan penerima implisit.
Ini juga berarti kita dapat memanggil metode pribadi dari dalam kelas yang dideklarasikan di dalam serta semua subclass dari kelas ini.
Anda tidak pernah dapat memanggil metode pribadi dari luar hirarki kelas di mana ia didefinisikan.
Metode yang dilindungi dapat disebut dengan penerima implisit, seperti halnya pribadi. Selain itu metode yang dilindungi juga dapat dipanggil oleh penerima eksplisit (hanya) jika penerima adalah "diri" atau "objek dari kelas yang sama".
Ringkasan
Publik: Metode publik memiliki visibilitas maksimum
Diproteksi: Metode terproteksi dapat dipanggil dengan penerima implisit, seperti private. Selain itu metode yang dilindungi juga dapat dipanggil oleh penerima eksplisit (hanya) jika penerima adalah "diri" atau "objek dari kelas yang sama".
Pribadi: Untuk metode pribadi di Ruby, itu tidak pernah bisa dipanggil dengan penerima eksplisit. Kami dapat (hanya) memanggil metode pribadi dengan penerima implisit. Ini juga berarti kita dapat memanggil metode pribadi dari dalam kelas yang dideklarasikan di dalam serta semua subclass dari kelas ini.
sumber
sumber