/* ************************************************************************* * 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_subclasse extends superclasse_ereditata {...}; * * Ossia al nome si aggiunge la parola chiave extends, seguita dalla * superclasse padre da cui si eredita il "patrimonio genetico" di metodi * e variabili. Dichiariamo la classe giraffa derivata da animale: * * class giraffa extends animale {...}; * * 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. * Le 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.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. * 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". ************************************************************************ */ import java.io.*; // Include le funzioni I/O standard di base. /* ********************************************************************** */ public class Jlez9a { // Da qua inizia la classe Jlez9a /////////////////////////////////////////////////////////////////////////// // Il main... /////////////////////////////////////////////////////////////////////////// public static void main(String args[]) // Definiamo il metodo Main. { // Inizio del main() animale cane1 = new animale(); // Istanzio un ogg. della classe animale // Chiediamo all'utente le informazioni. Oggetto di tipo animale: cane1. System.out.println("\nLunghezza cane 1?"); cane1.mettilungh(leggiFloat()); // Passa a mettilungh il valore letto. System.out.println("Num. zampe cane 1?"); cane1.mettizampe(leggiInt()); // Passa a mettizampe il val. letto. // Ora l'oggetto di tipo giraffa: carlotta. giraffa carlotta = new giraffa(); // Istanzio un oggetto di tipo giraffa // Chiediamo all'utente le informazioni. Oggetto di tipo giraffa: carlotta. System.out.println("Num. zampe carlotta?"); carlotta.mettizampe(leggiInt()); // Passa a mettizampe il val. letto. System.out.println("\nLunghezza Carlotta?"); carlotta.mettilungh(leggiFloat()); // Passa a mettilungh il valore letto. System.out.println("\nLunghezza collo Carlotta?"); carlotta.metticollo(leggiFloat()); // Passa a metticollo il valore letto. // Infine l'oggetto di tipo cervo: carlone. cervo carlone = new cervo(); // Istanzio un oggetto di tipo cervo System.out.println("Num. zampe carlone?"); carlone.mettizampe(leggiInt()); // Passa a mettizampe il val. letto. System.out.println("\nLunghezza Carlone?"); carlone.mettilungh(leggiFloat()); // Passa a mettilungh il valore letto. System.out.println("\nLunghezza corna Carlone?"); carlone.metticorna(leggiFloat()); // Passa a metticorna il valore letto. // Ora visualiziamo lo stato degli animali, usando i loro metodi di lettura. System.out.print("\nStato del cane1: zampe = " + cane1.leggizampe()); System.out.println(", lunghezza = " + cane1.leggilungh()); System.out.print("\nStato di carlotta: zampe = " + carlotta.leggizampe()); System.out.print(", lunghezza = " + carlotta.leggilungh()); System.out.println(", lunghezza collo = " + carlotta.leggicollo()); System.out.print("\nStato di carlone: zampe = " + carlone.leggizampe()); System.out.print(", lunghezza = " + carlone.leggilungh()); System.out.println(", lunghezza corna = " + carlone.leggicorna()); } // Fine del metodo principale Main() /* ------------------------------------------------------------------------- * Definiamo un metodo chiamato leggiInt(), che in entrata non ha * parametri, e in uscita restituisce un numero intero immesso da tastiera. * int leggiInt() * ----------------------------------------------------------------------- */ public static int leggiInt() { try { DataInputStream leggilo = new DataInputStream(System.in); String stringa = leggilo.readLine(); // dichiaro e leggo stringa. return(Integer.valueOf(stringa).intValue()); // e la converto in int. } catch (Exception e) { System.out.println("Errore: " + e + " nella lettura da tastiera"); System.exit(0); return(-1); // Questo return serve solo perche' il metodo // abbia un int di ritorno anche in caso di errore } } // Fine di "int leggiInt()" /* ------------------------------------------------------------------------- * Definiamo un metodo chiamato leggiFloat(), che in entrata non ha * parametri, e in uscita restituisce un numero float immesso da tastiera. * float leggiFloat() * ----------------------------------------------------------------------- */ public static float leggiFloat() { try { DataInputStream leggilo = new DataInputStream(System.in); String stringa = leggilo.readLine(); // dichiaro e leggo stringa. return(Float.valueOf(stringa).floatValue()); // e la converto in float. } catch (Exception e) { System.out.println("Errore: " + e + " nella lettura da tastiera"); System.exit(0); return(-1); // Questo return serve solo perche' il metodo // abbia un int di ritorno anche in caso di errore } } // Fine di "float leggiFloat()" } // Fine della classe Jlez9a /* ************************************************************************* * Definiamo la classe animale. Generera' il file animale.class. * Il compilatore dara' un warning (attenzione) perche' sarebbe preferibile * separare il listato della classe e compilarlo a parte in un file * chiamato animale.java. Comunque la compilazione avviene lo stesso. ************************************************************************ */ class animale { // Definisco la classe animale private float lunghezza=0; // Variabile privata private int numerozampe=0; // Variabile privata // Ora scriviamo i metodi pubblici della classe animale: /*-------------------------------------------------------------------------* * mettilungh: definisce la lunghezza dell'animale. * parametri: in entrata la lunghezza in formato float. *-------------------------------------------------------------------------*/ public void mettilungh(float i) { 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. *-------------------------------------------------------------------------*/ public void mettizampe(int l) { 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. *-------------------------------------------------------------------------*/ public float leggilungh() { return lunghezza; } /*-------------------------------------------------------------------------* * leggizampe: legge e restituisce il num. di zampe dell'animale. * parametri: in uscita il num. di zampe in formato int. *-------------------------------------------------------------------------*/ public int leggizampe() { return numerozampe; } } // Fine della classe animale /*************************************************************************** * Deriviamo due specie di animali particolari: giraffa e cervo. * Queste avranno da aggiungere al patrimonio 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 extends animale { // Classe giraffa derivata da animale. private float lungcollo; // Variabile privata peculiare di giraffa // Ora scriviamo i metodi pubblici della classe giraffa: /*-------------------------------------------------------------------------* * metticollo: definisce la lunghezza del collo della giraffa * parametri: in entrata la lungh. collo in formato float. *-------------------------------------------------------------------------*/ public void 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. *-------------------------------------------------------------------------*/ public float leggicollo() // leggicollo() e' un metodo di giraffa { return lungcollo; } } // Fine della classe giraffa /**************************************************************************/ // Ora deriviamo la classe cervo dalla superclasse animale. class cervo extends animale { // Classe cervo derivata da animale. private float lungcorna; // Variabile privata peculiare 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 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 leggicorna() // leggicorna() e' un metodo di cervo { return lungcorna; } } // Fine della classe giraffa /* ************************************************************************* * Questo sorgente crea ben 4 file: Jlez9a.class, animale.class, * giraffa.class e cervo.class. Quando il progetto cresce e si diversifica * puo' risultare piu' comodo dividere il sorgente, in modo da compilare * soltando le classi da finire. ************************************************************************ */