back to top

Il meccanismo di ereditarietà in C++

In C++, come in molti altri linguaggi di programmazione, le classi costituiscono uno strumento fondamentale. Una classe è, in sostanza, un insieme di dati e di metodi.

  • I dati rappresentano informazioni (ad esempio nome, cognome, ecc.).
  • I metodi invece sono funzioni che possono essere applicate ai dati (si pensi ad esempio ad un semplice metodo "stampa" per visualizzare a schermo tutti i dati all’interno della classe).
public class Persona 
{
    ...//dati
    ...//metodi
}
Una classe identifica non tanto un singolo elemento di interesse, quanto un gruppo di elementi con caratteristiche simili (non, ad esempio, il singolo impiegato Mario Rossi, ma l’insieme degli impiegati di una certa ditta).

Il singolo elemento (ad esempio una persona specifica) è invece un oggetto. L’oggetto è un particolare membro di una classe o, utilizzando una terminologia più corretta, un’istanza di una classe.

Il meccanismo di ereditarietà, presente con forza nel linguaggio C++, consente un migliore e più efficiente utilizzo delle classi nella programmazione. In particolare, l’ereditarietà consente di riutilizzare classi già realizzate in nuovi contesti, con un notevole risparmio in termini di tempo e di impegno. Viene garantita inoltre una migliore leggibilità del codice.

Immaginiamo, per comprendere il funzionamento di tale meccanismo, di avere precedentemente realizzato una classe Veicolo, per rappresentare un generico mezzo di trasporto. I dati in esso contenuti saranno, ad esempio, la lunghezza del veicolo, il numero di posti, la velocità di punta raggiungibile.

public class Veicolo
{
  int lunghezza;
  int nposti;
  int velmassima;
  //metodi
}    
A questo punto immaginiamo di voler sviluppare una classe Automobile, per rappresentare un particolare tipo di veicolo. Un’automobile infatti è anche un veicolo. Si dice, in questo caso, che tra la classe Automobile e la classe Veicolo esiste una relazione di tipo is-a.

E’ proprio l’esistenza di tale relazione che consente un utilizzo efficiente del meccansimo di ereditarietà. Infatti è possibile fare in modo che la classe Automobile “erediti” ovvero abbia a disposizione e possa utilizzare dati e metodi propri della classe Veicolo, che viene definita classe base.

Ciascun oggetto di tipo Automobile, che viene definito di classe derivata, fornisce dunque, nel caso in esame, informazioni riguardo la lunghezza, il numero di posti e la velocità massima. Inoltre ciascun oggetto di tipo Automobile avrà anche a disposizione un dato marca di tipo String (serie di caratteri alfanumerici), che non è invece presente per un oggetto di tipo Veicolo. Ciò viene realizzato in questo modo:

public class Automobile: public Veicolo
{
    String marca;
    ...
}
Se in una relazione di ereditarietà tra classi si identifica una sola classe base si parla di ereditarietà semplice, come in questo caso. La classe Automobile infatti eredita soltanto dalla classe Veicolo.

Il C++ inoltre, a differenza di molti altri linguaggi di programmazione, supporta anche soluzioni dal potenziale ancora maggiore: si tratta, in sostanza, di meccansimi di ereditarietà multipla.

Ereditarietà multipla

Per comprendere il funzionamento dell’ereditarietà multipla supponiamo di avere a disposizione, oltre alla classe Veicolo, anche una classe Casa.

public class Casa
{
   int metriquadrati;
   ...
}
Possiamo decidere ora di voler realizzare una classe Camper. La classe Camper presenterà caratteristiche tipiche di un veicolo e caratteristiche tipiche di una casa. Si può dire, con una certa approssimazione, che un camper sia un veicolo e, allo stesso tempo, che il camper sia una casa.

In forza delle considerazioni già effettuate in precedenza a proposito della relazione is-a, quindi, la classe Camper erediterà sia da Casa che da Veicolo.

public class Camper: public Veicolo, public Casa
{
  ...
}
La classe Camper avrà dunque a disposizione tutti i dati e i metodi propri sia della classe Veicolo che della classe Casa.

E’ possibile effettuare una gestione ancora più fine del meccanismo di ereditarietà, sia singola che multipla, servendosi della procedura detta di overriding dei metodi.

Overriding dei metodi

I metodi, come già ricordato, forniscono funzioni per la gestione e l’elaborazione dei dati. E’ possibile però che gli stessi dati debbano essere elaborati in maniera diversa secondo la classe di appartenenza.

Ad esempio, il numero dei posti potrebbe influenzare il prezzo di un’automobile in modo diverso rispetto ad un generico veicolo. Sarebbe dunque opportuno ridefinire le operazioni compiute da alcuni metodi senza rinunciare completamente ai vantaggi in termini di tempo e di semplificazione forniti dall’ereditarietà.

Ciò si realizza proprio tramite l’overriding dei metodi che si desidera modificare. Basterà dichiarare una seconda volta, all’interno della classe derivata, i metodi da ridefinire:

public class Veicolo
{
    ...
    virtual int calcolacosto();
    ...
}
public class Automobile: public Veicolo
{
    ...
    virtual int calcolacosto();
    ...
}
A questo punto sarà sufficiente sviluppare due funzioni distinte nelle due classi per il calcolo del costo, di nome calcolacosto. Automaticamente, grazie all’overriding dei metodi, il programma utilizzerà la funzione definita all’interno della classe Veicolo per oggetti di tipo Veicolo e la sostituirà con la funzione sviluppata all’interno della classe Automobile per oggetti di tipo Automobile.

L’overriding dei metodi consente pertanto, senza rinunciare ai vantaggi dell’ereditarietà, di determinare il costo in modo diverso a seconda che il generico veicolo sia o meno un’automobile.

Pubblicitร 

Leggi anche...

Radice quadrata in C: vediamo come calcolarla in diversi modi

La radice quadrata è un'operazione matematica piuttosto comune (in...

Sperimentare la sequenza di Collatz in C++

Vediamo come verificare la congettura di Collatz con C++....

Calcolare la radice quadrata con Python

In Python è possibile calcolare la radice quadrata usando...

12 film che ogni programmatore dovrebbe guardare (per trovare ispirazione e creatività)

Molti ragazzi hanno deciso di intraprendere una carriera da...

Cartonizzare una foto con Python e la libreria OpenCV

La cartoonization è una procedura grafica che consente di...

Creare flowchart (diagrammi di flusso) online: 5 strumenti gratuiti

Hai bisogno di realizzare una flow chart ma non...
Pubblicitร