Fondamenti di Informatica L-B Esercitazione n 4 Java: I/O, Costruttori e altro A.A. 2005/06 Tutor: Loris Cancellieri loris.cancellieri@studio.unibo.it Riferimenti ad oggetti: Cosa si può fare con i riferimenti? Contatore c; Usarli per creare nuovi oggetti: c = new Contatore(); Assegnarli uno all altro: Contatore c2 = c; In tal caso, l oggetto referenziato è condiviso 2 Riferimenti ad oggetti: (Esempio) Uguaglianza tra oggetti Alla luce di quello che abbiamo visto sopra che significato ha c1==c2??? c1 e c2 sono due riferimenti e sono uguali solo se puntano entrambi allo stesso oggetto. Qui c1==c2 è true! 3 4
Uguaglianza tra oggetti (2) E se si creano due oggetti identici? Contatore c1 = new Contatore(); Contatore c2 = new Contatore(); c1.azzera(); c2.azzzera(); Uguaglianza tra oggetti (3) Per verificare l uguaglianza tra i valori di due oggetti si usa il metodo equals public boolean equals(object o) invocato con c1.equals(c2) che però deve essere definito all interno della classe counter: Il contenuto non conta: qui c1==c2 è false!!! 5 public class Contatore { private int valore;........ public boolean equals (Contatore x) { return (val == x.val); consideriamo uguali due Contatori solo se hanno lo stesso valore interno, ma ogni altro metodo èlecito! 6 Costruttori Costruttori: Esempio Molti errori nel software sono causati da mancate inizializzazioni di variabili public class Contatore { private int valore; Perciò i linguaggi a oggetti introducono il costruttore, un metodo particolare che automatizza l inizializzazione degli oggetti private int valmax; non viene mai chiamato esplicitamente dall utente è invocato automaticamente dal sistema ogni volta che si crea un public Contatore() { valore = 0; nuovo oggetto di quella classe. public Contatore(int v) { valore = v; public Contatore(int v1,int v2) { Il costruttore: valore = v1; valmax = v2; ha un nome fisso, uguale al nome della classe non ha tipo di ritorno, neppure void il suo scopo infatti non è calcolare qualcosa, ma inizializzare un public void incrementa() { val++; oggetto public int leggi() { return val; può non essere unico e spesso vi sono più costruttori, con diverse liste di parametri (servono a inizializzare l oggetto a partire da public boolean equals(counter x) situazioni diverse) 7 8
Costruttori: un cliente public class Testcontatore { Contatore c1; Contatore c2; senza argomenti Contatore c3; c1 = new Contatore(); a due argomenti c2 = new Contatore(2,10); c3 = new Contatore(3); ad un argomento c1.inc(); c2.inc(); c3.inc(); System.out.println( Il contatore c1 vale +c1.leggi()); System.out.println( Il contatore c2 vale +c2.leggi()); System.out.println( Il contatore c3 vale +c3.leggi()); Ancora sui costruttori Il costruttore senza parametri si chiama costruttore di default viene usato per inizializzare oggetti quando non si specificano valori iniziali esiste sempre: se non lo definiamo noi, ne aggiunge uno il sistema però, il costruttore di default definito dal sistema non fa (quasi) nulla: quindi, è opportuno definirlo sempre. DOMANDA: È possibile che un parametro del costruttore sia omonimo con il nome di un dato? Ad esempio, se Contatore contiene un campo valore, può un costruttore avere un parametro di nome anch'esso valore? E se sì, come si risolve questa ambiguità? 9 10 La parola chiave this Input da tastiera / file Package Fiji L ambiguità si risolve con la parola chiave this public Contatore(int valore){ this.valore = valore; La parola this identifica l'istanza corrente, cioè l'oggetto su cui si sta operando di norma è sottintesa: ad esempio, in un metodo di Counter, scrivere valore o this.valore èidentico: public void inc() { this.valore++; viene resa esplicita solitamente per risolvere omonimie fra nomi di parametri e nomi di dati come appunto in: public Contatore(int valore){ this.valore = valore; 11 Per leggere da tastiera / file usiamo il package fiji. Il package fiji contiene una classe Lettore che implementa vari metodi per la lettura di linee, stringhe,interi, double, etc..per tutti i metodi si veda la documentazione allegata Esempio: import fiji.io.*; public class TestLettore { Lettore input = new Lettore(); String s = input.leggilinea(); System.out.println("Ho letto: "+s); 12
La classe Lettore La classe Lettore ha tre costruttori: La classe Lettore (2) import fiji.io.*; 13 //Provo la lettura da File public class TestLettore2 { String fname = "intervista.txt"; try { Lettore input = new Lettore(new FileReader(fname)); while (!input.eof()) { String s = input.leggilinea(); System.out.println("Ho letto: "+s); System.out.println("Lettura del file "+fname+" Terminata"); catch (Exception e) { e.printstacktrace(); 14 Il package Java di I/O Il package Java di I/O (2) Per la scrittura (lettura) su file facciamo uso del package java.io e quindi quando lo utilizziamo dobbiamo fare Il concetto base utilizzato dal java è quello dello STREAM Uno stream è un canale di comunicazione monodirezionale (o di input, o di output) di uso generale adatto a trasferire byte (o anche caratteri) 15 16
Tassonomia: Classi Base Scrittura su File 17 Per la scrittura su file faremo uso del package java di I/O FileWriter fout = null; try { fout = new FileWriter("file1.txt"); chiamo ESPLICITAMENTE i metodi tostring della classi catch(ioexception e){ associate ai tipi di dato primitivi buffer = Float.toString(f1)+" "; fout.write(buffer,0,buffer.length()); buffer = " "+Integer.toString(12)+" "; fout.write(buffer,0,buffer.length()); fout.close(); 18 Scrittura su File (2) //Apro il file con append a false BufferedWriter out = new BufferedWriter(new FileWriter( file1.txt", false)); int x = 12; String s = x vale +x; Più semplice poiché out.write(s+"\n"); costruisco la stringa e poi out.newline(); la stampo senza bisogno di chiamare esplicitamente i out.flush(); tostring out.close(); NB Cosa farete ora? Ora che conosciamo come funziona l I/O in Java riscriviamo in questo linguaggio l applicazione ContaParole vista in C (si sfrutti la classe Contatore che abbiamo costruito) Modifichiamo la classe Contatore inserendo i costruttori visti prima e implementando per ora il metodo equals e sperimentarlo attraverso l uso di TestContatore In seguito sfruttare la classe TestContatore o la classe ContaParole per sperimentare i metodi di scrittura su file, lettura di parametri da tastiera. Sempre per esercizio costruire una semplice applicazione che effettui la copia di un file di testo e cioè effettui la lettura del file usando la classe Lettore e poi scriva il contenuto letto in un altro file sfruttando le classi FileWriter o BuffererWriter (preferibile) 19 20