Saya selalu menyukai gagasan memiliki banyak warisan yang didukung dalam suatu bahasa. Paling sering meskipun itu sengaja dilupakan, dan seharusnya "penggantian" adalah antarmuka. Antarmuka tidak mencakup semua tanah yang sama dengan pewarisan berganda, dan pembatasan ini kadang-kadang dapat menyebabkan lebih banyak kode boilerplate.
Satu-satunya alasan dasar yang pernah saya dengar untuk ini adalah masalah berlian dengan kelas dasar. Aku tidak bisa menerimanya. Bagi saya, itu keluar dari banyak sekali seperti, "Yah, itu mungkin untuk mengacaukannya, jadi itu secara otomatis ide yang buruk." Anda dapat mengacaukan apa pun dalam bahasa pemrograman, dan maksud saya apa pun. Saya tidak bisa menganggap ini serius, setidaknya bukan tanpa penjelasan yang lebih mendalam.
Menyadari masalah ini adalah 90% dari pertempuran. Terlebih lagi, saya pikir saya mendengar sesuatu bertahun-tahun yang lalu tentang penyelesaian untuk keperluan umum yang melibatkan algoritma "amplop" atau sesuatu seperti itu (apakah ini membunyikan bel, siapa pun?).
Mengenai masalah berlian, satu-satunya masalah yang berpotensi asli yang dapat saya pikirkan adalah jika Anda mencoba menggunakan perpustakaan pihak ketiga dan tidak dapat melihat bahwa dua kelas yang tampaknya tidak terkait di perpustakaan itu memiliki kelas dasar yang sama, tetapi selain itu dokumentasi, fitur bahasa yang sederhana dapat, katakanlah, mengharuskan Anda secara khusus menyatakan niat Anda untuk membuat berlian sebelum benar-benar mengkompilasi untuk Anda. Dengan fitur seperti itu, setiap ciptaan berlian adalah disengaja, sembrono, atau karena orang tidak menyadari jebakan ini.
Jadi, semua itu dikatakan ... Apakah ada alasan nyata mengapa kebanyakan orang membenci banyak warisan, atau apakah itu semua hanya histeria yang menyebabkan lebih banyak kerugian daripada kebaikan? Adakah sesuatu yang tidak saya lihat di sini? Terima kasih.
Contoh
Mobil meluas WheeledVehicle, KIASpectra memperluas Mobil dan Elektronik, KIASpectra berisi Radio. Mengapa KIASpectra tidak mengandung Elektronik?
Karena ini elektronik. Pewarisan vs komposisi harus selalu berupa hubungan is-a vs. has-a.
Karena ini elektronik. Ada kabel, papan sirkuit, sakelar, dll semuanya naik turun.
Karena ini elektronik. Jika baterai Anda mati di musim dingin, Anda berada dalam banyak masalah seolah-olah semua roda Anda tiba-tiba hilang.
Mengapa tidak menggunakan antarmuka? Ambil nomor 3, misalnya. Saya tidak ingin menulis ini berulang-ulang, dan saya benar - benar tidak ingin membuat kelas pembantu proxy yang aneh untuk melakukan ini juga:
private void runOrDont()
{
if (this.battery)
{
if (this.battery.working && this.switchedOn)
{
this.run();
return;
}
}
this.dontRun();
}
(Kami tidak membahas apakah implementasi itu baik atau buruk.) Anda dapat membayangkan bagaimana mungkin ada beberapa fungsi yang terkait dengan Elektronik yang tidak terkait dengan apa pun di WheeledVehicle, dan sebaliknya.
Saya tidak yakin apakah akan menerima contoh itu atau tidak, karena ada ruang untuk interpretasi di sana. Anda juga bisa berpikir dalam hal Pesawat memperluas Kendaraan dan FlyingObject dan Burung memperluas Hewan dan FlyingObject, atau dalam hal contoh yang jauh lebih murni.
Traits
- mereka bertindak seperti antarmuka dengan implementasi opsional, tetapi memiliki beberapa batasan yang membantu mencegah masalah seperti masalah berlian muncul.
KiaSpectra
bukan sebuah Electronic
; ia memiliki Elektronika, dan mungkin merupakan ElectronicCar
(yang akan memperpanjang Car
...)