class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Tolong lupakan desainnya. Saya tahu bahwa OOP menentukan bahwa objek pribadi bersifat pribadi untuk kelas. Pertanyaan saya adalah, mengapa OOP dirancang sedemikian rupa sehingga bidang privat memiliki akses tingkat kelas dan bukan akses tingkat objek ?
someMethod
tidak valid. Itu tidak mengembalikan apapun. Itu pastivoid
.Jawaban:
Saya juga agak penasaran dengan jawabannya.
Jawaban paling memuaskan yang saya temukan adalah dari Artemix di posting lain di sini (Saya mengganti nama AClass dengan kelas Person): Mengapa pengubah akses tingkat kelas daripada tingkat objek?
EDIT: Silakan pilih jawaban Artemix. Saya hanya menyalin-tempelnya.
sumber
Person
, di dalam kelasPerson
, tidak harus mengetahui implementasi seluruh kelas. Praktik yang baik adalah menggunakan pengakses, tanpa harus mengetahui operasi apa yang dilakukan pengakses.equals(Object)
metode di kelas Java untuk memeriksa kesetaraanPerson
objek dengan instance lainPerson
. Anda mungkin ingin mengaktifkan dunia luar untuk memeriksa apakah kedua contoh tersebut sama, tetapi Anda mungkin tidak ingin mengekspos semua bidang privat kelas yang diperlukan untuk memeriksa kesetaraan ke dunia luar menggunakan metode pengakses publik. Memiliki akses tingkat kelas keprivate
bidang memungkinkan penerapan metode seperti itu tanpa adanya kebutuhan untuk mengimplementasikan metode publik tersebut.equals
).equals
dapat dilakukan dengan memanggil pengakses pribadi.private
harus memberikan akses tingkat kelas. Saya setuju bahwa menggunakan pengakses umumnya merupakan kebiasaan yang baik, meskipun dalam hal ini sebagian besar adalah masalah konteks dan gaya pribadi. Perhatikan bahwa Joshua Bloch di Java Efektif (item 8) dan Tal Cohen di artikel Dr. Dobbs ini secara langsung mengakses bidang pribadi di daftar kode mereka saat membahas cara menerapkanequals
.Lihat Spesifikasi Bahasa Java, Bagian 6.6.1. Menentukan Aksesibilitas
Ini menyatakan
Klik link di atas untuk lebih jelasnya. Jadi jawabannya adalah: Karena James Gosling dan penulis Java lainnya memutuskan demikian.
sumber
Pertanyaan bagus. Tampaknya pengubah akses tingkat objek akan memberlakukan prinsip Enkapsulasi lebih jauh.
Tapi sebenarnya yang terjadi adalah sebaliknya. Mari kita ambil contoh. Misalkan Anda ingin menyalin jauh objek dalam konstruktor, jika Anda tidak dapat mengakses anggota pribadi objek itu. Maka satu-satunya cara yang mungkin adalah menambahkan beberapa pengakses publik ke semua anggota pribadi. Ini akan membuat objek Anda telanjang ke semua bagian lain dari sistem.
Jadi enkapsulasi tidak berarti tertutup bagi seluruh dunia. Itu berarti menjadi selektif tentang siapa yang Anda ingin terbuka.
sumber
o.deepCopy()
atau apa pun.Ini berfungsi karena Anda berada di
class Person
- kelas diizinkan untuk menyodok di dalam jenis kelasnya sendiri. Ini sangat membantu ketika Anda ingin menulis konstruktor salinan, misalnya:class A { private: int x; int y; public: A(int a, int b) x(a), y(b) {} A(A a) { x = a.x; y = y.x; } };
Atau jika kita ingin menulis
operator+
danoperator-
untuk kelas angka besar kita.sumber
Hanya 2 sen saya pada pertanyaan mengapa semantik visibilitas pribadi di Jawa adalah tingkat kelas daripada tingkat objek.
Saya akan mengatakan bahwa kenyamanan tampaknya menjadi kuncinya di sini. Faktanya, visibilitas pribadi di tingkat objek akan memaksa untuk mengekspos metode ke kelas lain (misalnya dalam paket yang sama) dalam skenario yang diilustrasikan oleh OP.
Sebenarnya saya tidak dapat membuat atau menemukan contoh yang menunjukkan bahwa visibilitas di tingkat kelas-privat (seperti yang ditawarkan oleh Java) menciptakan masalah apa pun jika dibandingkan dengan visibilitas di tingkat objek-pribadi.
Meskipun demikian, bahasa pemrograman dengan sistem kebijakan visibilitas yang lebih terperinci dapat memberikan visibilitas objek pada level objek dan level kelas.
Misalnya Eiffel , menawarkan ekspor selektif: Anda dapat mengekspor fitur kelas apa pun ke kelas apa pun pilihan Anda, dari {NONE} (object-private) hingga {ANY} (setara dengan publik, dan juga default), ke {PERSON} (kelas-pribadi, lihat contoh OP), untuk kelompok kelas tertentu {PERSON, BANK}.
Menarik juga untuk berkomentar bahwa di Eiffel Anda tidak perlu membuat atribut menjadi pribadi dan menulis getter untuk mencegah kelas lain menetapkannya. Atribut publik di Eiffel secara default dapat diakses dalam mode hanya-baca, jadi Anda tidak memerlukan pengambil hanya untuk mengembalikan nilainya.
Tentu saja Anda masih memerlukan penyetel untuk menyetel atribut, tetapi Anda dapat menyembunyikannya dengan mendefinisikannya sebagai "pemberi tugas" untuk atribut itu. Ini memungkinkan Anda, jika ingin, menggunakan operator penetapan yang lebih nyaman daripada pemanggilan penyetel.
sumber
Karena
private
pengubah akses membuatnya hanya terlihat di dalam kelas . Metode ini masih DI dalam kelas .sumber
yang
private
bidang diakses di kelas / objek di mana lapangan dinyatakan. Ini bersifat pribadi untuk kelas / objek lain di luar tempatnya berada.sumber
Hal pertama di sini yang harus kita pahami adalah yang harus kita lakukan adalah harus mengikuti prinsip-prinsip oops sehingga enkapsulasi mengatakan bahwa membungkus data dalam paket (yaitu kelas) dan kemudian merepresentasikan semua data sebagai Object dan mudah diakses. jadi jika kita membuat field sebagai non-private daripada diakses secara indivisual. dan itu menghasilkan paratice yang buruk.
sumber
Dengan konsep refleksi di Jawa dimungkinkan untuk memodifikasi bidang dan metode privat
Mengubah metode penyimpanan pribadi dengan Refleksi di Java
sumber