/* E' giunto il momento di sperimentare l'ereditarieta'.
* Abbiamo una classe animale (superclasse), dalla quale possiamo derivare
* sottoclassi di specie animali, ad esempio le specie giraffa e cervo.
* Queste subclassi erediteranno le variabili lunghezza e numerozampe,
* nonche' i metodi mettilungh(), mettizampe(), leggilungh() e leggizampe().
* A queste variabili e metodi, comuni a tutti gli animali, aggiungeremo
* manualmente le variabili e i metodi specifici della classe derivata.
* In particolare, la classe derivata giraffa avra' in piu' una variabile
* lungcollo e un paio di metodi pubblici, metticollo() e leggicollo(), in
* modo da poter interfacciare tale variabile (privata) con l'esterno.
* La classe derivata cervo, invece, avra' una variabile lungcorna e i
* relativi metodi metticorna() e leggicorna().
* Per derivare una classe da un'altra, si usa questa sintassi:
*
* class nome_nuova_classe : superclasse_ereditata {...};
*
* Ossia al nome si aggiunge il simbolo ":" seguito dalla superclasse padre
* da cui si eredita il "patrimonio genetico" di metodi e variabili.
* Ad esempio, dichiariamo la classe giraffa derivata da animale:
*
* class giraffa : animale {...};
*
* Si puo' anche specificare un identificatore di accesso, che noi metteremo
* sempre public. Ecco quindi la classe figlia giraffa derivata da animale:
*
* class giraffa : public animale {
* float lungcollo; // var. privata peculiare di giraffa
* public: // La parte che segue e' PUBLIC
* void metticollo(float cl); // Prototipi delle funzioni
* float leggicollo(void); // peculiari di giraffa.
* };
*
* A questo punto possiamo agevolmente definire i suoi metodi:
*
* void giraffa::metticollo(float cl) // un metodo di giraffa
* {
* lungcollo = cl; // accedo a una variabile di giraffa.
* }
*
* A questo punto definire la subclasse cervo o altre non dovrebbe esservi
* difficile.
* Nel listato si potranno usare contemporaneamente istanze della
* superclasse animale e delle due classi derivate.
* Ricordo che la classe e' un tipo astratto usato per definire soltanto
* l'organizzazione di variabili e istruzioni di un dato oggetto, e non
* e' l'oggetto fisico utlilizzabile. Nel listato non si puo' pensare di
* eseguire giraffa.leggicollo(). Bensi', si dovra' istanziare (ossia
* creare fisicamente) un oggetto di tipo giraffa, cioe' un oggetto ( di
* cui decidiamo il nome) la cui organizzazione interna e' stata definita
* astrattamente nella classe giraffa: Il nome puo' essere Carlotta: a
* questo punto avremo un esemplare, ossia un oggetto di quella classe,
* chiamato Carlotta, e utilizzabile.
* Ad esempio Fuffy e Buby sono istanze della razza (classe) cane.
* La classe astratta "cane" non mangia, non beve, non abbaia, non si puo'
* vedere, ne' toccare, ma solo pensare, in quanto e' un concetto teorico
* che definisce e classifica un insieme di cose che effettivamente abbaiano,
* e hanno nomi come Fuffy o Buby.
* Queste classi sono organizzate in modo gerarchico, infatti se vediamo
* una giraffa allo Zoo che si chiama Carlotta, vediamo un oggetto fisico,
* istanziato, utilizzabile in un listato. Pero' riconosciamo che e' una
* giraffa, e che le giraffe sono animali. Gli animali si possono distinguere
* dalle piante per il fatto che hanno le zampe al posto delle radici e le
* foglie, e le giraffe si possono distinguere dagli altri animali per il
* collo lungo e il colore giallo a macchiette. Le giraffe inoltre hanno
* in comune con i cervi l'appartenenza alla classe animale, e la non
* appartenenza alla classe vegetale. Dunque si puo' ricostruire una
* gerarchia simile alle diramazioni di un albero (genealogico, se si vuole),
* che e' il modo piu' naturale per l'uomo di pensare e classificare le cose.
* La programmazione ad oggetti infatti tende ad essere piu' vicina al modo
* di pensare dell'uomo.
* Si possono derivare da giraffa varie sottospecie di giraffe, ognuna delle
* quali si potrebbe dividere nelle 2 classi maschio e femmina, e cosi' via.
* Nel listato istanzieremo un esemplare della superclasse animale, che
* chiameremo cane1 (consideriamolo un animale senza segni particolari),
* e un esemplare per ognuna delle due subclassi, giraffa e cervo, che
* chiameremo rispettivamente carlotta e carlone.
* Sarebbe piu' logico derivare una subclasse cane da animale per definire
* cane1, ma lo scopo del listato e' di dimostrare che si possono usare
* contemporaneamente sia la classe "genitore" che le classi "figlie".
* Anche in questo esempio definiamo variabili e oggetti dinamicamente
* nel momento in cui servono.
*/
#include <iostream.h> // Header necessario per usare CIN e COUT
// Questo e' un commento C++ ad una sola linea
class animale { // Definisco la classe animale
float lunghezza; // Questa parte e' PRIVATE di default
int numerozampe;
public: // La parte che segue e' PUBLIC
void mettilungh(float i); // Questi sono i prototipi delle funzioni
void mettizampe(int l); // (o metodi) della nostra classe.
float leggilungh(void);
int leggizampe(void);
};
// Ora scriviamo le funzioni (metodi) della classe animale:
/*-------------------------------------------------------------------------*
* mettilungh: definisce la lunghezza dell'animale.
* parametri: in entrata la lunghezza in formato float.
*-------------------------------------------------------------------------*/
void animale::mettilungh(float i) // mettilungh() e' un metodo di animale
{
lunghezza = i; // Scrive il valore nella variabile privata "lunghezza".
}
/*-------------------------------------------------------------------------*
* mettizampe: definisce il numero di zampe dell'animale.
* parametri: in entrata il num. di zampe in formato int.
*-------------------------------------------------------------------------*/
void animale::mettizampe(int l) // mettizampe() e' un metodo di animale
{
numerozampe = l; // Scrive il valore nella variabile privata "numerozampe".
}
/*-------------------------------------------------------------------------*
* leggilungh: legge e restituisce la lunghezza dell'animale.
* parametri: in uscita la lunghezza in formato float.
*-------------------------------------------------------------------------*/
float animale::leggilungh(void) // leggilungh() e' un metodo di animale
{
return lunghezza;
}
/*-------------------------------------------------------------------------*
* leggizampe: legge e restituisce il num. di zampe dell'animale.
* parametri: in uscita il num. di zampe in formato int.
*-------------------------------------------------------------------------*/
int animale::leggizampe(void) // leggizampe() e' un metodo di animale
{
return numerozampe;
}
/***************************************************************************
* Deriviamo due specie di animali particolari: giraffa e cervo.
* Queste avranno da aggiungere al partimonio ereditato le caratteristiche
* peculiari della propria specie: la lunghezza del collo la giraffa, e
* e la lunghezza delle corna il cervo.
* In seguito istanzieremo dei cervi e delle giraffe fisiche con un nome
* proprio, ovvero istanzieremo degli oggetti di tipo giraffa e cervo.
**************************************************************************/
// Iniziamo derivando la classe giraffa dalla superclasse animale.
class giraffa : public animale { // Classe giraffa derivata da animale.
float lungcollo; // PRIVATE - variabile peculiare di giraffa
public: // La parte che segue e' PUBLIC
void metticollo(float cl); // Questi sono i prototipi delle funzioni
float leggicollo(void); // peculiari di giraffa.
};
/*-------------------------------------------------------------------------*
* metticollo: definisce la lunghezza del collo della giraffa
* parametri: in entrata la lungh. collo in formato float.
*-------------------------------------------------------------------------*/
void giraffa::metticollo(float cl) // metticollo() e' un metodo di giraffa
{
lungcollo = cl; // Scrive il valore nella variabile privata "leggicollo".
}
/*-------------------------------------------------------------------------*
* leggicollo: legge e restituisce la lunghezza del collo della giraffa.
* parametri: in uscita la lunghezza del collo in formato float.
*-------------------------------------------------------------------------*/
float giraffa::leggicollo(void) // leggicollo() e' un metodo di giraffa
{
return lungcollo;
}
/**************************************************************************/
// Ora deriviamo la classe cervo dalla superclasse animale.
class cervo : public animale { // Classe cervo derivata da animale.
float lungcorna; // PRIVATE - variabile peculiare di cervo
public: // La parte che segue e' PUBLIC
void metticorna(float cn); // Questi sono i prototipi delle funzioni
float leggicorna(void); // peculiari di cervo.
};
/*-------------------------------------------------------------------------*
* metticorna: definisce la lunghezza delle corna del cervo
* parametri: in entrata la lungh. corna in formato float.
* NB: non allude ne' ha a che vedere con le corna coniugali.
*-------------------------------------------------------------------------*/
void cervo::metticorna(float cn) // metticorna() e' un metodo di cervo
{
lungcorna = cn; // Scrive il valore nella variabile privata "leggicorna".
}
/*-------------------------------------------------------------------------*
* leggicorna: legge e restituisce la lunghezza delle corna del cervo.
* parametri: in uscita la lungh. delle corna in formato float.
*-------------------------------------------------------------------------*/
float cervo::leggicorna(void) // leggicorna() e' un metodo di cervo
{
return lungcorna;
}
///////////////////////////////////////////////////////////////////////////
// Il main...
///////////////////////////////////////////////////////////////////////////
int main(void)
{
animale cane1; // Istanzio un oggetto della classe animale
// Chiediamo all'utente le informazioni. Oggetto di tipo animale: cane1.
cout << "\nNum. zampe cane 1? "; // Stampa la frase.
int temp2; // Var. temporanea per il num. zampe.
cin >> temp2; // Legge il valore.
cane1.mettizampe(temp2); // Passa a mettizampe la variabile temp2
cout << "Lunghezza cane 1? "; // Stampa la frase come un printf()
float temp; // Var. temporanea per la lunghezza.
cin >> temp; // Legge il valore come scanf()
cane1.mettilungh(temp); // Passa a mettilungh la variabile temp
// Ora l'oggetto di tipo giraffa: carlotta.
giraffa carlotta; // Istanzio un oggetto di tipo giraffa
cout << "Num. zampe carlotta? "; // Stampa la frase come un printf()
cin >> temp2; // Legge il valore come scanf()
cout << "Lunghezza carlotta? "; // Stampa la frase come un printf()
cin >> temp; // Legge il valore come scanf()
carlotta.mettizampe(temp2); // Passa a mettizampe la variabile temp2
carlotta.mettilungh(temp); // Passa a mettilungh la la lunghezza.
cout << "Lunghezza collo di carlotta? "; // Stampa la frase.
cin >> temp; // Legge il valore come scanf()
carlotta.metticollo(temp); // Passa a metticollo la variabile temp
// Infine l'oggetto di tipo cervo: carlone.
cervo carlone; // Istanzio un oggetto di tipo cervo
cout << "Num. zampe carlone? "; // Stampa la frase come un printf()
cin >> temp2; // Legge il valore come scanf()
cout << "Lunghezza carlone? "; // Stampa la frase come un printf()
cin >> temp; // Legge il valore come scanf()
carlone.mettizampe(temp2); // Passa a mettizampe la variabile temp2
carlone.mettilungh(temp); // Passa a mettilungh la la lunghezza.
cout << "Lunghezza corna di carlone? "; // Stampa la frase.
cin >> temp; // Legge il valore come scanf()
carlone.metticorna(temp); // Passa a metticorna la variabile temp
// Ora visualiziamo lo stato degli animali, usando i loro metodi di lettura.
cout << "\nStato dell'animale cane1: zampe = " << cane1.leggizampe();
cout << ", lunghezza = " << cane1.leggilungh();
cout << "\nStato della giraffa carlotta: zampe = " << carlotta.leggizampe();
cout << ", lunghezza = " << carlotta.leggilungh();
cout << ", collo m. = " << carlotta.leggicollo();
cout << "\nStato del cervo carlone: zampe = " << carlone.leggizampe();
cout << ", lunghezza = " << carlone.leggilungh();
cout << ", corna cm. = " << carlone.leggicorna();
return 0; // main() restituisce 0
}
/* Per derivare una classe, in Java al posto dei : si usa la parola "extends"
* ad esempio la giraffa si deriva cosi':
*
* public class giraffa extends animale { ... }
*
* anziche':
*
* class giraffa : public animale { ... };
*
* In effetti quei due punti (:) si possono interpretare come "estende",
* in quanto una classe derivata e' un'estensione della sua superclasse.
*/
