Si è visto come tra i capisaldi della programmazione ad oggetti, l'ereditarietà svolga una funzione molto importante e faciliti parecchio il disegno e la codifica dei programmi. Esistono, però, delle circostanze in cui può aver senso far derivare una classe da più classi padre: è il caso dell'ereditarietà multipla.
Supponiamo di voler implementare una classe Mezzo Anfibio (un tipo di veicolo capace di camminare sia sulla terra che sull'acqua). Avvalendoci dei discorsi di astrazione dei dati ed ereditarietà fatti in precedenza potremmo tracciare il seguente diagramma di classi:
Come è facile intuire osservando la figura (in cui la gerarchia di eredità è ora rappresentata da un grafo aciclico), la classe Mezzo Anfibio, per le sue caratteristiche particolari, erediterà i metodi e le proprietà con access specifier public e protected sia dalla classe Veicolo Terrestre che dalla classe Veicolo Acquatico.
In generale, c'è da dire che l'ereditarietà multipla pur rappresentando una notevole potenzialità nel mondo Object Oriented, favorendo notevolmente la flessibilità e il riutilizzo del codice, viene solitamente considerata un approccio da evitare a causa della complessità che può derivare da una siffatta architettura. In particolare, i due problemi principali che possono sorgere quando si utilizza l'eredità multipla sono i seguenti:
- Ambiguità dei nomi
- Poca efficienza nella ricerca dei metodi definiti nelle classi
Il primo problema (Ambiguità dei nomi) può verificarsi se una proprietà o un metodo ereditato è definito con lo stesso nome in tutte le classi padre di una data classe. Ad esempio, rifacendoci all'esempio della figura precedente, se la Classe Veicolo Terrestre e la classe Veicolo Acquatico implementassero entrambe i metodi svolta_a_dx() e svolta_a_sx()ciò porterebbe ad un problema di ambiguità per la classe Mezzo_Anfibio nell'ereditare tali metodi da entrambe le classi.
Il secondo problema (Poca Efficienza nella ricerca dei metodi definiti nelle classi) è causato dalla nuova struttura che assume l'architettura in questo tipo di approccio che, come detto, è adesso rappresentata da un grafo. Infatti, con l'utilizzo di una struttura a grafo non è più possibile utilizzare la ricerca lineare (ideale sulle strutture ad albero) per l'individuazione dei metodi ma è necessario effettuare una sorta di "backtracking" sul grafo stesso.
L'ereditarietà multipla, proprio per le controverse questioni riguardanti il suo utilizzo, non è implementata in tutti i linguaggi di programmazione ad oggetti. Il C++ e Python rappresentano due esempi di linguaggi che consentono l'utilizzo di tale implementazione mentre linguaggi come Java, C# e VB.Net eliminano il problema alla radice, non consentendo ad alcuna classe di avere più di una classe padre.
Implementare l'ereditarietà multipla
Ecco come si implementa l'ereditarietà multipla in alcuni dei linguaggi orientati agli oggetti per il web.