/* ************************************************************************* * Nei listati fino ad ora abbiamo creato delle classi, ma non abbiamo avuto * mai modo di istanziare una nostra classe nel main di un'altra classe. * Come abbiamo visto, ogni classe crea un file .class col nome della * classe stessa. Se si definiscono piu' classi nello stesso sorgente.java, * da esso dopo la compilazione verranno creati i vari file class. * La separazione delle classi quindi e' proprio "fisica": files diversi! * Abbiamo visto che una classe si crea in questo modo: * * [accesso] [modificatori] class nomeclasse { ... } * * In [accesso] si puo' facoltativamente mettere public, protected o * private, che determinano la visibilita' della classe rispetto alle * altre. In altre parole determinano il livello di accesso. * Una classe/variabile/metodo PUBLIC e' visibile da tutte le classi * esterne, ossia i metodi delle altre classi possono accederci. * Dichiarare tutto public semplifica le cose ai principianti, ma rende * piu' pericoloso il lavoro agli esperti. * Che livello di protezione viene assegnato se non si mette niente? * ad esempio se si scrive semplicemente "int i;" o "class bau{..}"? * Si ha un livello di protezione simile a public, ma un po' piu' * ristretto, in quanto non si puo' accedere dal di fuori del package.. * Comunque non e' possibile specificare "manualmente" questo tipo di * accesso con una parola chiave, l'unico modo e non metterne alcuna. * Non abbiamo ancora spiegato bene i package, quindi sorvoliamo. * Un po' piu' restrittivo e' l'accesso di tipo PROTECTED, che permette * l'accesso solo alla stessa classe e alle classi derivate, figlie. * Attenzione al fatto che occorre scrivere PRIVATE PROTECTED, e non * solo PROTECTED per ottenere questo livello di protezione. * Il livello di protezione piu' alto e' PRIVATE, che rende visibili * metodi e variabili soltanto alle classi in cui sono definite. * Tutto cio' che non serve alle classi esterne e che non deve essere * condiviso con esse, deve essere reso private, in modo da rendere * effettivamente impossibile un caso di accesso dall'esterno. * Rese private queste variabili, saranno utilizzabili dalle classi * esterne attraverso i metodi pubblici della classe, mai direttamente. * Molto semplicemente, dovremo definire 2 classi anziche' 1 nel prossimo * sorgente: la prima sara' quella principale, con il main(), nella * quale istanzieremo oggetti della seconda classe. * Il nostro scopo e' di entrare nella filosofia object oriented un po' * meglio di quanto abbiamo fatto fino ad ora. Definire tutti i metodi e * le variabili come public e/o static porta a usare il Java come un * lunguaggio non OO, e cio' limita molto le sue possibilita'. * Vediamo quindi l'uso di una classe con dati privati e metodi pubblici. * Ricordiamoci di istanziare gli oggetti con l'operatore "new". ************************************************************************* */ import java.io.*; // Include le funzioni I/O standard di base. // La classe Jlez7b e' quella da eseguire, che conterra' il main() e // che istanziera' un oggetto dalla classe animale. Da notare che // questo sorgente crea due file: Jlez7b.class e animale.class /* ********************************************************************** */ public class Jlez7b { // Da qua inizia la classe Jlez7b /////////////////////////////////////////////////////////////////////////// // Il main... /////////////////////////////////////////////////////////////////////////// public static void main(String args[]) // Definiamo il metodo Main. { // Inizio del main() // Ora possiamo dichiarare alcuni oggetti di tipo animale e usarli: animale cane1 = new animale(); // ecco che dichiaro 3 animali animale cane2 = new animale(); // ossia creo degli esemplari dalla animale millepiedi = new animale(); // classe "astratta" // Non possiamo accedere direttamente ai dati degli oggetti, sono privati. // Con cane1.numerozampe = 4 otterremmo un errore di compilazione. // Ora dobbiamo mandare un messaggio all'oggetto chiedendogli di modificare // la sua variabile. cane1.mettizampe(4); // Chiamiamo il metodo mettizampe() di cane1 cane2.mettizampe(4); // e quello di cane2, per variare le loro millepiedi.mettizampe(1000); // variabili private. Stesso per millepiedi // cane1.numerozampe = 4; // Abilitate questa istruzione illegale // per ottenere un errore in compilazione. // Gli altri parametri li chiediamo all'utente. System.out.println("\nLunghezza cane 1?"); cane1.mettilungh(leggiFloat()); // Passa a mettilungh il valore letto. System.out.println("Lunghezza cane 2?"); cane2.mettilungh(leggiFloat()); // Passa a mettilungh il valore letto System.out.println("Lunghezza millepiedi?"); millepiedi.mettilungh(leggiFloat()); System.out.println("Num. esatto piedi del millepiedi?"); millepiedi.mettizampe(leggiInt()); // Passa a mettizampe il val. 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 del cane2: zampe = " + cane2.leggizampe()); System.out.println(", lunghezza = " + cane2.leggilungh()); System.out.print("\nStato del millepiedi: zampe = " + millepiedi.leggizampe()); System.out.println(", lunghezza = " + millepiedi.leggilungh()); } // 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 Jlez7b /* ************************************************************************* * Definiamo la classe animale. Generera' il file animale.class. * Il compilatore dara' un warning (attenzione) nel caso che la classe * fosse public, 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 /* ************************************************************************* * Questo e' il nostro primo programma diviso in 2 file .class. * Provate a togliere il // all'istruzione che scrive illegalmente nella * variabile privata di un istanza di animale, e noterete come in fase * di compilazione si presenti un errore, con tanto di testo esplicativo. * Avrete notato come ogni metodo sia preceduto da un campo di commento * in cui si definisce chiaramente il suo scopo, e in particolare * i parametri in entrata ed uscita. Il programma funziona anche senza * commenti, ma con essi diventa comprensibile anche ad altri, e a noi, * nel caso si rispolverasse dopo anni, una volta dimenticato tutto. * Purtroppo molti non commentano assolutamente i listati, e cio' lo credo * un errore grave quanto quelli che causano malfunzionamenti. ************************************************************************* */