La parte peggiore dell'eredità multipla è l'ereditarietà del diamante, in cui una sottoclasse ha due o più percorsi verso lo stesso genitore da qualche parte lungo la catena. Questo crea ambiguità se le implementazioni differiscono lungo i due percorsi (cioè sono sovrascritte dall'implementazione originale). In C++ la soluzione è particolarmente brutta: si incorporano entrambe le classi parent incompatibili e si deve specificare quando si chiama quale implementazione si desidera. Ciò crea confusione, crea lavoro extra in ogni sito di chiamata (o, più probabilmente, ti costringe a sovrascrivere esplicitamente e indica quello che desideri, questo lavoro manuale è tedioso e introduce una possibilità di errore) e può portare a oggetti più grandi di dovrebbero essere.
Scala risolve alcuni ma non tutti i problemi limitando l'ereditarietà multipla ai tratti. Poiché i tratti non hanno costruttori, la classe finale può linearizzare l'albero di ereditarietà, vale a dire che anche se due genitori su un percorso di ritorno a un super-genitore comune nominalmente sono entrambi genitori, uno è quello "corretto", vale a dire quello elencato per ultimo. Questo schema lascerebbe intere classi half-initialized spezzate se potessi avere costruttori (completamente generici), ma così com'è, non devi incorporare la classe due volte, e al sito use puoi ignorare quanta ereditarietà se ne ha è accaduto. Tuttavia, non è molto più facile ragionare su ciò che accadrà quando si sovrappongono molti tratti l'uno sull'altro, e se erediti sia da B
sia da C
, non è possibile scegliere di prendere di di B
le implementazioni e alcune delle C
.
Quindi è meglio in quanto affronta alcune delle critiche più gravi del modello C++. Se sia meglio è una questione di gusti; molte persone amano anche il gusto dell'eredità multipla del C++ abbastanza bene da usarlo.
fonte
2013-06-01 19:16:00
Per favore, date un'occhiata al libro [Programming in Scala] (http://www.artima.com/pins1ed/traits.html#12.6), pagina 258, §12.6. Ho trovato questa spiegazione estremamente valida e potrei provare a riformularla, ma non lo farei - è difficile scrivere qualcosa di più completo di così. In breve, in Scala non esiste il cosiddetto [* diamond problem *] (https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem) (che esiste in C++ ed è per questo che l'eredità multipla di C++ è stata criticata così male) , a causa della mancanza di costruttori, ordine di invocazione del metodo ben definito e nozione differente di * super *. –