CORSO DI INTERFACCE UTENTE - INTERFACCE GRAFICHE ================================================ LABORATORIO DEI GIORNI 11-12 APRILE 2002 ================================================ COMMENTI ALL'ESERCIZIO 1 ===Variabili che rappresentano lo stato interno=== Nell'esempio lo stato interno di un punto e' dato dalle due coordinate (x,y). Ci sono due alternative: (1) Definire le variabili dello stato interno come pubbliche. In questo modo, dall'esterno posso direttamente usarle in espressioni e assegnazioni (sia a destra che a sinistra). Per es. se p e' un punto, posso scrivere p.x e p.y in contesti come: a = p.x; // accesso in lettura p.x = a; // accesso in scrittura (2) Definirle come private. In questo caso la classe che implementa il punto deve fornire metodi per leggere e per assegnare x ed y: public double getX() { return x; } public double getY() { return y; } public setX(double val) { x = val; } public setY(double val) { y = val; } Il modo (1) va bene se non c'e' pericolo che un accesso incontrollato (specialmente in scrittura) possa portare ad uno stato interno inconsistente. Nel caso del punto non c'e' pericolo perche' qualunque coppia (x,y) denota un punto. Il modo (2) si usa quando invece il pericolo c'e'. Es: una classe che implementa un codice fiscale (il quale e' una stringa costruita secondo regole ben precise, non una stringa qualsiasi) e' opportuno che abbia la variabile privata e due metodi get e set, dove il metodo set si occupera' di controllare che la stringa obbedisca alle regole. ===Funzioni matematiche=== Tutte le funzioni matematiche (per es. la radice quadrata sqrt) sono implementate nella classe Math. [Vedere classe Math nella API in linea] In C: #include nel sorgente e compilazione con l'opzione -lm per linkare la libreria matematica In Java: niente di tutto questo, basta premettere Math. alla funzione che si adopera, es: Math.sqrt(2.0); ===Scrittura su standard input e standard error=== Si ottengono con System.out.print o System.out.println System.err.print o System.err.println Dal punto di vista "oggetti", System e' una classe che rappresenta il sistema su cui java sta girando. [Vedere classe System nella API in linea] Questo sistema ha (fra tante altre cose) due oggetti al suo interno: out ed err, entrambi di classe PrintStream (cioe' sono file su cui si puo' stampare) [Vedere classe PrintStream nella API in linea] La classe PrintStream prevede i metodi print o println (il secondo va a capo dopo avere scritto) per scrivere una stringa sul file. Java converte automaticamente qualunque cosa in stringa tramite l'operatore di concatenazione + (concatenazione di stringhe). Per es. posso scrivere System.out.println("Il valore e' " + v); dove v e' una variabile numerica, e viene stampata la stringa "Il valore e' " seguita dalla stringa che rappresenta il valore di v. COMMENTI ALL'ESERCIZIO 2 Niente di nuovo rispetto all'esercizio 1. Da notare che, mentre la classe MyPoint dell'esercizio 1 e' una classe "vera", la classe Hypotenuse di questo esercizio e' solo un pretesto per ospitare un metodo "main" che faccia il lavoro di calcolo. In pratica non corrisponde a nessun tipo di oggetti. Devo definirla perche' in java non posso scrivere procedure al di fuori di una classe. COMMENTI ALL'ESERCIZIO 3 ===Generazione dell'anagramma=== Per generare un anagramma di una stringa s si puo' procedere cosi': - Inizialmente l'anagramma di s e' uguale ad s. - Successivamente viene rimescolato scambiando due a caso dei suoi caratteri, per un certo numero di volte (per es. pari alla lunghezza di s). Occorre generare due numeri casuali nell'intervallo da 0 ad l-1, dove l e' la lunghezza della stringa s. Si puo' usare un generatore casuale, fornito dalla classe Random. [Vedere classe Random nella API in linea] Siccome questa classe si trova nel package accessorio "util", per poterla usare bisogna aggiungere in cima al sorgente la linea: import java.util.*; Il metodo della classe da usare per generare un numero casuale e': nextInt(int upper_bound) ===Creazione di una stringa=== Il tipo stringa in java e' realizzato dalla classe String [Vedere classe String nella API in linea] che pero' non permette di modificare una stringa. Il corrispettivo modificabile e' la classe StringBuffer. [Vedere classe StringBuffer nella API in linea] Questa e' la classe da usare per costruire l'anagramma. Si puo' poi trasformare un oggetto StringBuffer in un oggetto String con: String s = new String(b); dove b e' un oggetto di classe StringBuffer. ===Lettura da standard input=== La classe System (gia' menzionata) contiene l'oggetto in, di classe InputStream, che corrisponde allo standard input. [Vedere classe InputStream nella API in linea] La classe InputStream contiene un metodo read che permette di leggere dei caratteri ritornandone il codice come numero intero. Nell'esempio dobbiamo leggere l'indice tra 0,1,2,3 della stringa da indovinare. Leggiamo dunque il codice del carattere immesso dall'utente, lo convertiamo in carattere e poi lo confrontiamo con i caratteri '0', '1', '2', '3'. int codice = System.in.read(); char carattere = (char)codice; switch (carattere) { case '0': ... case '1': ... ... } Il metodo read puo' sollevare un'eccezione (errore a run-time) che va gestito nel programma, altrimenti il compilatore si lamenta. Il modo piu' facile e' dire che l'eventuale errore si ripercuote all'esterno, mettendo la dicitura "throws Exception" nel metodo dove appare l'istruzione e in tutti quelli che lo chiamano, fino al main. Es: se read e' chiamata nel main, basta scrivere: public static void main (String args[]) throws Exception Per leggere piu' di un carattere? Posso leggere una linea di input (fino al ritorno a capo) e ottenerla come stringa usando un "reader", cioe' un tipo di oggetto che serve a leggere: BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String s = br.readLine(); System.out.println("Ho letto ["+s+"]"); La prima linea prende System.in (lo standard input), ci costruisce attorno un InputStreamReader, e poi converte quest'ultimo in un reader di tipo piu' raffinato, il BufferedReader. La classe BufferedReader contiene il metodo readLine. Per usare il codice soprastante bisogna importare il package java.io.