Non è una questione di quale sia il migliore, ma di quando usare cosa.
Nei casi "normali" è sufficiente una semplice domanda per scoprire se abbiamo bisogno di ereditarietà o aggregazione.
- Se La nuova classe è più o meno la classe originale. Usa l'ereditarietà. La nuova classe è ora una sottoclasse della classe originale.
- Se la nuova classe deve avere la classe originale. Usa aggregazione. La nuova classe ha ora la classe originale come membro.
Tuttavia, c'è una grande area grigia. Quindi abbiamo bisogno di molti altri trucchi.
- Se abbiamo usato l'ereditarietà (o abbiamo in programma di usarlo) ma utilizziamo solo parte dell'interfaccia o siamo costretti a sovrascrivere molte funzionalità per mantenere logica la correlazione. Quindi abbiamo un odore sgradevole che indica che abbiamo dovuto usare l'aggregazione.
- Se abbiamo usato l'aggregazione (o abbiamo in programma di usarlo) ma scopriamo che dobbiamo copiare quasi tutte le funzionalità. Quindi abbiamo un odore che punta nella direzione dell'eredità.
Per farla breve. Dovremmo usare l'aggregazione se parte dell'interfaccia non viene utilizzata o deve essere cambiata per evitare una situazione illogica. Dobbiamo solo utilizzare l'ereditarietà, se abbiamo bisogno di quasi tutte le funzionalità senza grandi cambiamenti. E in caso di dubbio, utilizzare Aggregazione.
Un'altra possibilità per, nel caso in cui abbiamo una classe che ha bisogno di parte della funzionalità della classe originale, è quella di dividere la classe originale in una classe radice e in una sottoclasse. E lascia che la nuova classe erediti dalla classe radice. Ma dovresti occupartene, non creare una separazione illogica.
Consente di aggiungere un esempio. Abbiamo una classe "Cane" con metodi: "Mangia", "Cammina", "Abbaia", "Gioca".
class Dog
Eat;
Walk;
Bark;
Play;
end;
Ora abbiamo bisogno di una classe "Gatto", che ha bisogno di "Mangia", "Cammina", "Fusa" e "Gioca". Quindi prima prova ad estenderlo da un cane.
class Cat is Dog
Purr;
end;
Sembra, va bene, ma aspetta. Questo gatto può abbaiare (gli amanti dei gatti mi uccideranno per questo). E un gatto che abbaia viola i principi dell'universo. Quindi dobbiamo scavalcare il metodo Bark in modo che non faccia nulla.
class Cat is Dog
Purr;
Bark = null;
end;
Ok, funziona, ma ha un cattivo odore. Quindi proviamo un'aggregazione:
class Cat
has Dog;
Eat = Dog.Eat;
Walk = Dog.Walk;
Play = Dog.Play;
Purr;
end;
Ok, è carino Questo gatto non abbaia più, nemmeno silenzioso. Ma ha ancora un cane interno che vuole uscire. Quindi proviamo la soluzione numero tre:
class Pet
Eat;
Walk;
Play;
end;
class Dog is Pet
Bark;
end;
class Cat is Pet
Purr;
end;
Questo è molto più pulito. Nessun cane interno. E cani e gatti sono allo stesso livello. Possiamo anche introdurre altri animali domestici per estendere il modello. A meno che non sia un pesce o qualcosa che non cammina. In tal caso, dobbiamo nuovamente rifattorizzare. Ma questo è qualcosa per un'altra volta.