Untuk memperjelas, yang saya tanyakan adalah
public class A{
private/*or public*/ B b;
}
vs.
public class A{
private/*or public*/ class B{
....
}
}
Saya pasti dapat memikirkan beberapa alasan untuk menggunakan satu atau yang lain, tetapi apa yang saya benar-benar ingin lihat adalah contoh meyakinkan yang menunjukkan bahwa pro dan kontra bukan hanya akademis.
object-oriented-design
class-design
EpsilonVector
sumber
sumber
Jawaban:
Mereka biasanya digunakan ketika kelas adalah detail implementasi internal dari kelas lain daripada bagian dari antarmuka eksternal. Sebagian besar saya melihatnya sebagai kelas hanya data yang membuat struktur data internal lebih bersih dalam bahasa yang tidak memiliki sintaks terpisah untuk struct gaya-c. Mereka juga berguna kadang-kadang untuk objek turunan satu metode yang sangat dikustomisasi seperti penangan acara atau utas pekerja.
sumber
Misalkan Anda sedang membangun pohon, daftar, grafik, dan sebagainya. Mengapa Anda harus mengekspos detail internal sebuah node atau sel ke dunia luar?
Siapa pun yang menggunakan grafik atau daftar harus hanya mengandalkan antarmuka, bukan implementasinya, karena Anda mungkin ingin mengubahnya suatu hari di masa mendatang (misalnya dari implementasi berbasis array ke yang berbasis pointer) dan klien menggunakan Anda struktur data ( masing-masing dari mereka ) harus memodifikasi kode mereka agar mencukupi untuk implementasi baru.
Alih-alih, merangkum implementasi sebuah node atau sel dalam kelas dalam pribadi memberi Anda kebebasan untuk memodifikasi implementasi kapan saja Anda perlu, tanpa klien dipaksa untuk menyesuaikan kode mereka secara konsekuen, selama antarmuka struktur data Anda tetap ada tidak tersentuh.
Menyembunyikan detail implementasi struktur data Anda juga mengarah pada keuntungan keamanan, karena jika Anda ingin mendistribusikan kelas Anda, Anda hanya akan membuat file antarmuka yang tersedia bersama dengan file implementasi yang dikompilasi dan tidak ada yang akan tahu jika Anda benar-benar menggunakan array atau pointer. untuk implementasi Anda, dengan demikian melindungi aplikasi Anda dari semacam eksploitasi atau, setidaknya, pengetahuan karena ketidakmungkinan untuk menyalahgunakan atau memeriksa kode Anda. Selain masalah praktis, tolong jangan meremehkan fakta bahwa ini adalah solusi yang sangat elegan dalam kasus seperti itu.
sumber
Menurut pendapat saya itu adalah polisi yang adil untuk menggunakan kelas yang ditentukan secara internal untuk kelas yang digunakan secara singkat di kelas untuk memungkinkan tugas tertentu.
Misalnya, jika Anda perlu mengikat daftar data yang terdiri dari dua kelas yang tidak terkait:
Jika kelas internal Anda digunakan oleh kelas lain, Anda harus memisahkannya. Jika kelas internal Anda mengandung logika apa pun, Anda harus memisahkannya.
Pada dasarnya, saya pikir mereka bagus untuk memasukkan lubang pada objek data Anda, tetapi mereka sulit untuk dipertahankan jika mereka benar-benar mengandung logika, karena Anda harus tahu di mana mencarinya jika Anda perlu mengubahnya.
sumber
tuple.ItemX
membuat kode tidak jelas.Kelas batin dalam beberapa bahasa (Java misalnya) memiliki ikatan ke objek kelas yang mengandung mereka dan dapat menggunakan anggota mereka tanpa kualifikasi mereka. Jika tersedia, lebih jelas daripada mengimplementasikannya menggunakan fasilitas bahasa lain.
Kelas bersarang dalam bahasa lain (C ++ misalnya) tidak memiliki ikatan seperti itu. Anda cukup menggunakan pelingkupan dan kontrol aksesibilitas yang disediakan oleh kelas.
sumber
Saya menghindari kelas batin di Jawa karena hot-swapping tidak berfungsi di hadapan kelas dalam. Saya benci ini karena saya benar-benar benci kompromi kode untuk pertimbangan seperti itu, tetapi restart Tomcat itu bertambah.
sumber
Salah satu kegunaan untuk private static internal adalah pola Memo. Anda memasukkan semua data yang perlu diingat ke dalam kelas privat dan mengembalikannya dari beberapa fungsi sebagai Object. Tidak seorang pun di luar tidak dapat (tanpa refleksi, deserialisasi, inspeksi memori ...) memeriksanya / memodifikasinya, tetapi ia dapat mengembalikannya ke kelas Anda dan dapat memulihkan kondisinya.
sumber
Salah satu alasan untuk menggunakan kelas dalam pribadi mungkin karena API yang Anda gunakan memerlukan warisan dari kelas tertentu, tetapi Anda tidak ingin mengekspor pengetahuan kelas itu ke pengguna kelas luar Anda. Sebagai contoh:
Dalam hal ini, do_my_async_op membutuhkan objek tipe callback untuk diteruskan ke sana. Callback ini memiliki tanda tangan fungsi anggota publik yang digunakan API.
Ketika do_op () dipanggil dari outer_class, ia menggunakan instance dari kelas dalam pribadi yang mewarisi dari kelas callback yang diperlukan alih-alih sebuah pointer ke dirinya sendiri. Kelas luar memiliki referensi ke kelas luar untuk tujuan sederhana shunting callback ke fungsi anggota do_callback pribadi kelas luar .
Manfaatnya adalah Anda yakin tidak ada orang lain yang dapat memanggil fungsi anggota "api ()" publik.
sumber
Menurut Jon Skeet dalam C # di Depth, menggunakan kelas bersarang adalah satu-satunya cara untuk mengimplementasikan singleton thread-safe yang sepenuhnya malas (lihat Versi Kelima) (hingga .NET 4).
sumber
Kelas privat dan batin digunakan untuk meningkatkan level enkapsulasi dan menyembunyikan detail implementasi.
Dalam C ++, selain kelas privat, konsep yang sama dapat dicapai dengan mengimplementasikan namespace anonim kelas cpp. Ini berfungsi dengan baik untuk menyembunyikan / memprivatisasi detail implementasi.
Ini adalah ide yang sama dengan kelas dalam atau pribadi tetapi pada tingkat enkapsulasi yang lebih besar karena sama sekali tidak terlihat di luar unit kompilasi file. Tidak ada yang muncul di file header atau secara kasat mata terlihat dalam deklarasi kelas.
sumber