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