Java menghilangkan banyak pewarisan dengan alasan bahwa ia menghilangkan tujuan desain untuk menjaga bahasa tetap sederhana .
Saya ingin tahu apakah Java (dengan sistem ramah lingkungannya) benar-benar "sederhana". Python tidak kompleks dan memiliki banyak pewarisan. Jadi tanpa terlalu subjektif, pertanyaan saya adalah ...
Apa pola masalah khas yang mendapat manfaat dari kode yang dirancang untuk memanfaatkan banyak pewarisan berganda
multiple-inheritance
treecoder
sumber
sumber
Jawaban:
Pro:
Cons:
Dalam C ++ contoh bagus dari multiple inheritance yang digunakan untuk fitur orthogonal komposit adalah ketika Anda menggunakan CRTP untuk, misalnya, menyiapkan sistem komponen untuk gim.
Saya sudah mulai menulis contoh tapi saya pikir contoh dunia nyata lebih layak untuk dilihat. Beberapa kode Ogre3D menggunakan banyak pewarisan dengan cara yang bagus dan sangat intuitif. Sebagai contoh, kelas Mesh mewarisi dari Resources dan AnimationContainer. Sumber daya mengekspos antarmuka umum untuk semua sumber daya dan AnimationContainer mengekspos antarmuka khusus untuk memanipulasi serangkaian animasi. Mereka tidak terkait, jadi mudah untuk berpikir tentang Mesh sebagai sumber daya yang di samping itu dapat menampung serangkaian animasi. Terasa alami bukan?
Anda dapat melihat contoh lain di perpustakaan ini , seperti cara alokasi memori dikelola dengan cara butiran halus dengan membuat kelas mewarisi dari varian kelas CRTP kelebihan beban baru dan hapus.
Seperti yang dikatakan, masalah utama dengan pewarisan berganda muncul dari pencampuran konsep terkait. Itu membuat bahasa harus mengatur implementasi yang kompleks (lihat cara C ++ memungkinkan untuk bermain dengan masalah berlian ...) dan pengguna tidak yakin apa yang terjadi dalam implementasi itu. Misalnya, baca artikel ini menjelaskan bagaimana ini diterapkan di C ++ .
Menghapusnya dari bahasa membantu menghindari orang-orang yang tidak tahu bagaimana bahasa tersebut membuat informasi menjadi buruk. Tapi itu memaksa untuk berpikir dengan cara yang, kadang-kadang, tidak terasa alami, bahkan jika itu kasus tepi, itu terjadi lebih sering yang mungkin Anda pikirkan.
sumber
Ada konsep yang disebut mixin yang banyak digunakan dalam bahasa yang lebih dinamis. Multiple inheritance adalah salah satu cara di mana mixin dapat didukung oleh suatu bahasa. Mixin umumnya digunakan sebagai cara bagi kelas untuk mengakumulasi berbagai fungsi. Tanpa pewarisan berganda, Anda harus menggunakan agregasi / delegasi untuk mendapatkan perilaku tipe mixin dengan kelas, yang sedikit lebih sintaksisnya.
sumber
Saya pikir pilihannya terutama didasarkan pada masalah karena masalah berlian .
Selain itu, sering kali mungkin untuk menghindari penggunaan pewarisan berganda dengan delegasi atau cara lain.
Saya tidak yakin tentang arti pertanyaan terakhir Anda. Tetapi jika itu "dalam kasus mana pewarisan berganda berguna?", Maka dalam semua kasus di mana Anda ingin memiliki objek A yang memiliki fungsi objek B dan C, pada dasarnya.
sumber
Saya tidak akan mempelajari banyak hal di sini, tetapi Anda pasti dapat memahami banyak warisan dalam python melalui tautan berikut http://docs.python.org/release/1.5.1p1/tut/multiple.html :
...
Ini hanya paragraf kecil tapi cukup besar untuk menghapus keraguan yang kurasa.
sumber
Satu tempat di mana pewarisan berganda akan berguna adalah situasi di mana sebuah kelas mengimplementasikan beberapa antarmuka, tetapi Anda ingin memiliki beberapa fungsi bawaan bawaan untuk setiap antarmuka. Ini berguna jika sebagian besar kelas yang mengimplementasikan beberapa antarmuka ingin melakukan sesuatu dengan cara yang sama, tetapi kadang-kadang Anda perlu melakukan sesuatu yang berbeda. Anda dapat memiliki masing-masing kelas dengan implementasi yang sama, tetapi lebih masuk akal untuk mendorongnya ke satu lokasi.
sumber
Ini hanya satu contoh tapi saya rasa sangat berharga untuk meningkatkan keselamatan dan mengurangi godaan untuk menerapkan perubahan cascading di seluruh penelepon atau subkelas.
Di mana saya telah menemukan banyak pewarisan yang sangat berguna bahkan untuk antarmuka yang paling abstrak dan stateless adalah idiom antarmuka non-virtual (NVI) dalam C ++.
Mereka bahkan tidak benar - benar abstrak kelas dasar seperti antarmuka yang hanya memiliki sedikit implementasi bagi mereka untuk menegakkan aspek universal dari kontrak mereka, karena mereka tidak benar-benar mempersempit generalitas kontrak sehingga lebih baik menegakkannya .
Contoh sederhana (beberapa orang mungkin memeriksa apakah suatu pegangan file yang lewat terbuka atau semacamnya):
Dalam hal ini, mungkin
f
disebut oleh seribu tempat dalam basis kode, sementaraf_impl
ditimpa oleh seratus subclass.Akan sulit untuk melakukan pemeriksaan keamanan semacam ini di semua 1000 tempat yang memanggil
f
atau semua 100 tempat yang mengesampingkanf_impl
.Dengan hanya membuat titik entri ini ke fungsionalitas nonvirtual, itu memberi saya satu tempat sentral untuk melakukan pemeriksaan ini. Dan pemeriksaan ini tidak mengurangi abstraksi sedikit pun, karena hanya menyatakan prasyarat yang diperlukan untuk memanggil fungsi ini. Dalam arti tertentu, ini bisa saja memperkuat kontrak yang disediakan oleh antarmuka, dan menghilangkan beban memeriksa
x
input untuk memastikan itu sesuai dengan prasyarat yang valid di semua 100 tempat yang menimpanya.Ini adalah sesuatu yang saya harap setiap bahasa miliki, dan juga saya harapkan, bahkan dalam C ++, bahwa itu sedikit lebih merupakan konsep asli (mis: tidak mengharuskan kita untuk mendefinisikan fungsi terpisah untuk menimpanya).
Ini sangat berguna jika Anda tidak melakukan ini
assert
sebelumnya, dan menyadari bahwa Anda membutuhkannya nanti ketika beberapa tempat acak dalam basis kode menemukan nilai negatif yang diteruskanf
.sumber
Pertama: beberapa salinan kelas dasar (masalah C ++) & kopling ketat antara kelas dasar dan turunan.
Kedua: multiple inheritance dari interface abstrak
sumber