appunti didattici sulla programmazione con Java Questi appunti sono stati scritti per gli studenti di informatica del Liceo Copernico di Bologna per introdurre alla programmazione con il linguaggio Java. Nota per il lettore: Il presente materiale si configura come una bozza provvisoria e può contenere errori, omissioni e/o imprecisioni. Si invitano i docenti, gli studenti e le famiglie che vengono a contatto con il presente elaborato e che ne riscontrano errori o difetti di qualsiasi tipo di segnalarli ai docenti che ne hanno curato la stesura. Indirizzi cui inviare le segnalazioni: [email protected] [email protected] [email protected] [email protected] [email protected] appunti java 1.0 pag.2 Introduzione Cosa sono il codice SORGENTE e il codice OGGETTO ? Il CODICE SORGENTE è un listato in formato “text”, è il testo del programma scritto dall’utente ma non ancora COMPILATO. Il CODICE OGGETTO è il testo TRADOTTO dal COMPILATORE che, durante la fase di compilazione, ne verifica la sintassi e lo riscrive rendendolo eseguibile. Cosa sono i programmi Java ? Sono programmi, il cui CODICE SORGENTE è scritto con una sintassi molto simile a quella del C e C++, salvati in file di tipo testo con estensione .java. Il CODICE OGGETTO compilato è contenuto nei file con estensione .class. Un file COMPILATO con estensione .class ha un formato particolare detto UNICODE identico in qualsiasi sistema operativo (Win95 - NT - UNIX - MAC OS SOLARIS), e pronto per l’esecuzione. In JAVA si possono scrivere due tipologie di programmi sorgente, STANDALONE e APPLET, la loro struttura sintattica è parzialmente diversa, ma entrambi dopo la compilazione sono contenuti in un file con estensione .class. In cosa differiscono i programmi STANDALONE e APPLET ? Un programma di tipo STANDALONE COMPILATO può essere eseguito da solo su qualsiasi computer (con qualsiasi sistema operativo Win95 - NT - UNIX - MAC OS - SOLARIS) se si possiede Java Runtime Environment (JRE) messo a disposizione gratuitamente da SUN Microsystem. Un file di tipo APPLET compilato può essere eseguito solo all’interno del BROWSER (Netscape, Explorer, HotJava ecc.) disponibile nel proprio sistema. Si tratta di un programma compilato che può “viaggiare sulla rete” ed essere immediatamente eseguito dal Browser. Si può affermare che un file CLASS è un programma eseguibile come gli EXE ottenuti in Pascal ? Non del tutto. Un programma compilato è in formato UNICODE, identico per tutti i sistemi operativi, ma per essere eseguito deve essere ancora INTERPRETATO da JRE o dal BROWSER compatibile Java. Un programma Pascal compilato è già in formato eseguibile. Lo schema indica quali passi sono necessari per realizzare ed eseguire un programma Java. appunti java 1.0 Editor a scelta Compilatore JAVA, comando DOS : C:\javac xxx.java pag.3 salva File xxx.java codice sorgente in formato Text Compilazione Salva un File xxx.class in formato UNICODE Applet Interprete JAVA (per win95, Standalone Unix, Mac), comando: Interpretazione C:\java xxx.class Esecuzione codice macchina in esecuzione Browser (win95, Unix, Mac); si deve costruire un file HTML con TAG <APPLET> oppure comando: C:\appletviewer xxx.class Fig. 1 – Schema di produzione/esecuzione di un programma Java. 1. Elementi di sintassi di Java Java a differenza del Pascal non distingue tra Function e Procedure. In Pascal le Procedure si utilizzano se il sottoproblema da trattare riceve Nessuno, Uno o Più Dati in input e restituisce Nessuno, Uno o Più risultati in output. Le Function hanno invece la caratteristica di poter restituire un solo risultato non strutturato, con la sola eccezione del tipo string. In java i sottoproblemi si devono sempre codificare con una sintassi unica (molto simile a quella della Function del Pascal). Se si dovesse codificare in Pascal una procedura che stampi due numeri, uno decimale e un intero, l’interfaccia sarebbe la seguente: Procedure Stampa (r : real; a : integer); r ed a sono parametri (dati) di input della procedura “passati per valore”, non ci sono dati di output. la corrispondente in Java assumerebbe la seguente forma: public static void Stampa (float r, int a); i caratteri con cui sono scritte le parole chiave sono tutti minuscoli (java è text sensitive, in altre parole gli identificatori a minuscolo oppure A maiuscolo rappresentano due oggetti distinti). appunti java 1.0 pag.4 public static sono le parole chiave che individuano le caratteristiche della procedura progettata: public significa accessibile/invocabile da qualsiasi programma, static significa che è allocata in memoria in modo statico. (Il significato sarà comprensibile solo più avanti dopo aver acquisito maggiori conoscenze del linguaggio) void significa che la “function” progettata non restituisce risultati al programma chiamante, non ha output Il significato della parte restante dovrebbe essere comprensibile se si conosce il Pascal. Si tratta rispettivamente dell’identificatore della Function e dei parametri r ed a passati alla Function per valore. Sono i dati di input su cui lavora il sottoprogramma Stampa(). Se si dovesse realizzare un sottoprogramma che determina il massimo comun divisore tra due numeri naturali, in Pascal e in Java l’interfaccia avrebbe la seguente sintassi: Function Mcd(a,b:integer):integer; public static int Mcd( int a, int b); Si nota che è sufficiente indicare il tipo di dato (int) restituito come risultato. Se la procedura riceve un array la sua dimensione e restituisce un array ordinato distinto da quello di input si avrebbero le seguenti interfacce: [ Type vettore = array [1..100] of real; ] Procedura Ordina(V:vettore; dim:integer; Var A:vettore); public static float[] Ordina( float V[], int dim); Le “funzioni-procedure” java prendono il nome convenzionale di METODO. Un programma java completo è sempre costituito da un insieme di METODI del tipo di quelli descritti, tutti contenuti in un “involucro”, il programma, detto CLASSE. In particolare un programma “elementare” Java è una CLASSE dotata di un solo METODO: il metodo main(). Esempio 1 Programma che stampa nella finestra del monitor un messaggio. class Mio_prog { //classe Mio_prog = programma public static void main(String args[]) { // METODO main() System.out.println(“sono un programma.”); // istruzione di stampa. } } Descrizione sintassi: class Parola chiave di definizione di una classe. Un programma è una classe. E’ l’equivalente della parola PROGRAM in PASCAL. N.B.: Una classe può non essere un programma eseguibile. appunti java 1.0 {} public static String args[] System.out.println() pag.5 Le graffe aperte e chiuse corrispondono all’individuazione di un blocco. Sono l’equivalente di BEGIN END in PASCAL. Parola chiave, significa che il metodo e “public” cioè pubblico. Il main() deve sempre essere public. (Possono esistere anche metodi private o protected) Parola chiave, significa che il metodo main() è un metodo STATICO, cioè non allocato nella memoria dinamica. Il metodo main è SEMPRE presente in un programma STANDALONE e ha la funzione di avviare l’esecuzione. NON è presente in un’APPLET. Argomento o parametro sempre presente nel metodo main() e corrisponde alla definizione di un array di String. Si rimanda la trattazione ai capitoli successivi. Istruzione di stampa di una stringa nella finestra DOS di output. La stampa in una finestra grafica non si esegue con questa istruzione. Qual è la sintassi con la quale si codifica una classe in Java? La struttura di classe può rappresentare tre oggetti concettualmente distinti: 1. un programma STANDALONE dotato del “metodo” main() che è il programma principale di AVVIO. (L’esempio precedente era un programma di questo tipo) 2. un APPLET eseguibile solo tramite un BROWSER all’interno di un file HTML. (vedremo in seguito le differenze rispetto ad un programma standalone) 3. una CLASSE che definisce OGGETTI ed è usata da altri PROGRAMMI O APPLET. La classe è paragonabile ad una dichiarazione di RECORD, se contiene solo dati, ma anche ad una UNIT del Pascal, se contiene anche metodi. Corrisponde alla definizione (alla specifica) di un AbstractDataType (un nuovo tipo di dato dotato di operazioni proprie). Una classe, infatti, ha un nome, degli attributi e dei metodi. Il nome serve per identificare la classe, gli attributi sono le informazioni contenute nel “record” (i dati della classe) i metodi sono le operazioni (funzioni) eseguibili su quegli attributi. 2.1 La struttura di una CLASSE Per ciascuno dei tre casi elencati sopra la forma che assume una classe è la seguente: CLASSE STANDALONE ( è un programma che class Mio_prog { public static void main(String args[]) { String S=”sono un programma”; System.out.println(S); } } “funziona da solo”) // classe di tipo “programma” // METODO main() // dichiarazione e assegnazione // istruzione di stampa. appunti java 1.0 pag.6 CLASSE APPLET (è un’applicazione “scaricabile” dalla rete quando è inclusa in una pagina HTML, ed eseguibile solo dal BROWSER) import java.awt.*; import java.applet.*; public class Mio_applet extends Applet{ // CLASSE di tipo “applet” public String S; // ATTRIBUTO pubblico public void init(){ // METODO init( ) = di avvio: S="sono un applet"; // equivale al metodo main() } public void paint(Graphics g){ // METODO paint() = di scrittura sul g.drawString(S,20,20); //pannello grafico del Browser } } Per visualizzare un’APPLET è necessario costruire un file HTML (per esempio si può utilizzare Notepad di Windows, salvando il file come HTM o HTML) contenente un TAG <APPLET>. Aprendo tale pagina con il BROWSER, sarà visibile il risultato dell’esecuzione dell’Applet: <HTML> <BODY> <APPLET codebase="C:/cartella" code="Mio_applet.class" width=300 height=180> </APPLET> </BODY> </HTML> // // // // (1) (2) (3) (4) Note: (1) <Applet codebase= (2) code= (3) width= , height= (4) </Applet> indica il TAG di avvio dell’Applet; indica il percorso dove è memorizzato l’applet da eseguire; nel nostro caso indica dove si trova il file Mio_applet.class; indica il nome dell’applet da eseguire; indicano larghezza e altezza del pannello sul quale il Browser mostrerà i risultati dell’applet; indica il TAG di fine dell’Applet; CLASSE “PURA”: (è un blocco di codice non eseguibile, ma invocabile da un programma standalone o da un’applet) Esempio 2 Si desidera definire come unica struttura dati una coppia di numeri decimali da utilizzare in altri programmi. (E’ simile ad una dichiarazione di Record in Pascal) class coppia { public double x=0.0, y=0.0; } appunti java 1.0 pag.7 Esempio 3 Si desidera definire un “oggetto” cerchio dotato di opportuni attributi e di due soli metodi: uno per spostarlo e uno per cambiarne il colore. (E’ simile ad una UNIT del Pascal). import java.awt.*; // importa il package che contiene la classe Color class cerchio { private coppia centro; private double raggio; private Color colore=Color.black; /* si deve supporre che esista un oggetto Color che possa assumere i valori costanti Color.black, Color.red, Color.green. */ public cerchio(coppia a, double r) { centro = a; raggio = r; } public void sposta(double dx, double dy) { centro.x = centro.x+dx; centro.y = centro.y+dy; } public void cambia_colore(Color c) { colore = c; } } 2.2 Analisi dei due esempi di Classe Come e da chi può essere utilizzata la classe coppia ? Una coppia è un oggetto che deve essere creato (allocato) dal programma che intende usarlo. Per esempio un programma standalone potrebbe usare la coppia nel seguente modo: class programma_prova_coppia { public static void main(String arg[ ]) { coppia mia=new coppia(); System.out.println(“la coppia è : “ +mia.x+ “ ,” +mia.y); } } siccome il costruttore new coppia( ) genera una coppia con i valori di default, il programma stamperà: la coppia è 0.0, 0.0 Si noti che anche la classe cerchio utilizza negli attributi la classe coppia per definire le coordinate del centro. appunti java 1.0 pag.8 Da quali parti è costituita una classe ? La classe coppia ha solo la “parte” attributi e manca di qualsiasi metodo (o operazione) che intervenga sugli attributi. Gli attributi sono pubblici e questo significa che sono accessibili ad un programma esterno alla classe. La classe cerchio oltre agli attributi (centro, raggio, colore) ha anche un metodo costruttore (cerchio) e due metodi (sposta, cambia_colore). Gli attributi sono privati e questo significa che un programma esterno alla classe non può modificarli se non utilizzando i metodi che lo permettono. Il metodo sposta() consente di cambiare le coordinate del centro, il metodo cambia_colore() consente di mutare l’attributo colore. Non esiste la possibilità di cambiare il raggio del cerchio perché non è stato costruito nessun metodo con questa finalità. Come e da chi può essere utilizzata la classe cerchio ? Si fornisce di seguito un esempio di uso della classe cerchio: import java.awt.*; class programma_prova_cerchio { public static void main(String arg[ ]) { coppia mia=new coppia(); mia.x=100; mia.y=55; double k = 30; cerchio circ=new cerchio(mia, k); circ.sposta(10.5, 35); circ.cambia_colore(Color.green); } } // // // // // // la coppia avrà i valori 0, 0 assegno alla coppia 100, 55 k è il valore del raggio si crea il cerchio circ sposta il centro cambia il colore Attenzione: il programma di questo esempio, pur compilabile ed eseguibile, non mostra nulla sul video. Si limita a modificare nella memoria dinamica i valori degli attributi del cerchio. Per poter visualizzare l’oggetto cerchio e il suo spostamento, si dovrebbe dotare la classe cerchio di due metodi (che tralasciamo) uno per disegnare l’oggetto cerchio e l’altro per cancellarlo. Da notare che se un metodo ha lo stesso nome della classe si chiama METODO COSTRUTTORE e serve per ISTANZIARE (allocare) un OGGETTO del tipo descritto dalla classe. Se si definisce una classe senza costruttore, ne esiste sempre di default uno implicito e serve per generare l’oggetto. Questo costruttore implicito può essere invocato ed ha lo stesso nome della classe, ma non consente il passaggio di parametri (vedi l’invocazione del costruttore new coppia() nel programma_prova_coppia).