Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

L'ereditarietà

Dall'estensione dei concetti alla riusabilità.
Dall'estensione dei concetti alla riusabilità.
Link copiato negli appunti

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) quello che eredita tutte o parte delle proprietà e dei metodi definiti nell'oggetto padre (parent object).

È 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.

L'oggetto cane, per citarne uno, erediterà, quindi, tutte le caratteristiche dell'oggetto mammifero e a sua volta conterrà delle caratteristiche aggiuntive, distintive di tutti i cani come ad esempio: ringhiare o abbaiare.
Il paradigma OOP, ha quindi carpito l'idea dell'ereditarietà dal mondo reale, come mostrato nella figura seguente:

 

Figura 1. Esempio di classificazione
Esempio di classificazione

e, 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.

Ad esempio, se i mammiferi diventassero improvvisamente (e anche inverosimilmente!) degli animali a sangue freddo, soltanto l'oggetto padre mammifero necessiterà di tale variazione. Il gatto il cane, l'uomo, la balena, e tutti gli altri oggetti figli erediterebbero automaticamente la caratteristica di avere il sangue freddo, senza nessuna modifica.

Un esempio che metta in luce la potenza dell'ereditarietà, in un programma Windows object oriented potrebbe avere come oggetto fulcro le finestre associate al programma stesso. Supponiamo, ad esempio, che tale software utilizzi, in totale, 100 finestre differenti, visualizzabili a secondo del contesto in cui sta navigando l'utente.

Se, un giorno, si volesse inserire un campo comune a tutte le finestre del programma, in che modo sarà bene procedere? Se non avremo utilizzato la potenza dell'ereditarietà l'unica strada percorribile sarà quella di andarsi a prendere una per una tutte le definizioni delle finestre e inserire il nuovo campo.

Se, invece, si sarà utilizzato in maniera efficiente il paradigma Object Oriented, definendo una classe FinestraBase contenente tutte le caratteristiche comuni ad ogni finestra e derivando da tale classe tutte le finestre in gioco nel programma, allora la modifica sarà banalmente (allo stesso modo dell'esempio sui mammiferi) quella di inserire il nuovo campo nella classe FinestraBase. Graficamente:

 

Figura 2. Classificazione di oggetti software
Classificazione di oggetti software

Ancora un esempio. In un sistema bancario, si potrebbe utilizzare l'ereditarietà per definire tutte le tipologie di conto esistenti. Supponiamo che i conti possibili siano quattro : conti correnti bancario, libretti di risparmio, carte di credito e certificati di deposito.

Tutte queste differenti tipologie di conto hanno in comune alcune caratteristiche: un numero di conto, un tasso di interesse ed un sottoscrittore. In tal modo potremo creare un oggetto padre chiamato Conto che contenga tutte le caratteristiche comuni prima enunciate.

Gli oggetti figli, in aggiunta, avranno le loro specifiche caratteristiche definite nelle rispettive classi. Ad esempio, la carta di credito avrà un limite di spesa mentre il il conto corrente bancario avrà uno o più libretti di assegni associati. Anche in questo caso, le eventuali modifiche apportate alla classe padre saranno ereditate automaticamente da tutte le classi figlie.

È 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, secondo quanto si è detto in questo paragrafo, 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.

Implementare l'ereditarietà

Ecco come si implementa l'ereditarietà in alcuni dei linguaggi orientati agli oggetti per il web.

Ti consigliamo anche