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