/* 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. */