Ereditarietà informatica
L’ereditarietà costituisce il secondo principio fondamentale della programmazione ad oggetti. In generale, essa rappresenta un meccanismo che consente di creare nuovi oggetti che siano basati su altri già definiti.
Si definisce oggetto figlio (child object), sottoclasse o classe derivata quello che eredita tutte o parte delle proprietà e dei metodi definiti nell’oggetto padre (parent object), superclasse o classe base.
È semplice poter osservare esempi di ereditarietà nel mondo reale. Ad esempio, esistono al mondo centinaia tipologie diverse di mammiferi: cani, gatti, uomini, balene e così via. Ognuna di tali tipologie di mammiferi possiede alcune caratteristiche che sono strettamente proprie (ad esempio, soltanto l’uomo è in grado di parlare) mentre esistono, d’altra parte, determinate caratteristiche che sono comuni a tutti i mammiferi (ad esempio, tutti i mammiferi hanno il sangue caldo e nutrono i loro piccoli). Nel mondo Object Oriented, potremmo riportare tale esempio definendo un oggetto Mammifero che inglobi tutte le caratteristiche comuni ad ogni mammifero. Da esso, poi, deriverebbero gli altri child object: Cane, Gatto, Uomo, Balena, etc.
Pertanto lo stesso concetto viene applicato ai sistemi software che utilizzano tale tecnologia.
Uno dei maggiori vantaggi derivanti dall’uso dell’ereditarietà è la maggiore facilità nella manutenzione del software. Infatti, rifacendoci all’esempio dei mammiferi, se qualcosa dovesse variare per l’intera classe dei mammiferi, sarà sufficiente modificare soltanto l’oggetto padre per consentire che tutti gli oggetti figli ereditino la nuova caratteristica. Quando il principio di sostituibilità (principio dell’informatica che asserisce che, se S è un sottotipo di T, allora oggetti dichiarati di tipo T in un programma possono essere sostituiti con oggetti di tipo S , senza modificare alcuna delle funzionalità richieste al programma) è rispettato, l’ereditarietà può essere utilizzata per ottenere il cosiddetto polimorfismo. Se ben usato, esso permette di avere programmi flessibili, nel senso che permette di scrivere codice in grado di far fronte a necessità e modifiche future richiedendo correzioni minime e/o ben circoscritte
È importante, però chiarire un aspetto importante quando si parla di caratteristiche ereditate. Non sempre, infatti, un determinato metodo definito nella classe padre può produrre risultati corretti e congruenti con tutte le classi figlie. Ad esempio, supponiamo di aver definito una classe padre denominata Uccello, dalla quale faremo derivare le seguenti classi figlie: Passerotto, Merlo e Pinguino. Nella classe padre, avremo definito il metodo vola(), in quanto rappresenta un comportamento comune a tutti gli uccelli. In tal modo, tutte le classi figlie non avranno la necessità di implementare tale metodo ma lo erediteranno dalla classe Uccello. Purtroppo, però, nonostante il pinguino appartenga alla categoria degli uccelli, è noto che esso non è in grado di volare, seppur provvisto di ali. In questo caso, il metodo vola() definito nella classe Uccello, sicuramente valido per la stragrande maggioranza di uccelli, non sarà utile (anzi, sarà proprio sbagliato) per la classe Pinguino. Come comportarsi in questi casi?
In OOP, ogni oggetto derivante da una classe padre ha la possibilità di ignorare uno o più metodi in essa definiti riscrivendo tali metodi al suo interno. Questa caratteristica è nota come overriding.
Utilizzando la tecnica dell’overriding, la classe Pinguino reimplementerà al suo interno il metodo vola(), conservando, comunque, la possibilità di richiamare in qualunque momento, anche il metodo definito nella classe padre. In quest’ultimo caso si parlerà di overriding parziale.
Si parla di ereditarietà multipla nel caso in cui da una superclasse derivano più classi derivate.
Commenti
Posta un commento