CORSO DI LAUREA E DI DIPLOMA IN INFORMATICA UNIVERSITA DEGLI STUDI DI MILANO ANNO ACCADEMICO JAVA COME LINGUAGGIO PER LA PROGRAMMAZIONE CONCORRENTE E PER LA REALIZZAZIONE DI INTERFACCE GRAFICHE Gianfranco Prini DSI - Università di Milano
INTRODUZIONE MOTIVAZIONI, PEREQUISITI, ARGOMENTI
PERCHE' JAVA IN UN CORSO DI SISTEMI OPERATIVI? Strumento di laboratorio mediante il quale presentare e discutere esempi di programmazione concorrente (CP) Strumento di laboratorio mediante il quale presentare e discutere esempi di programmazione di interfacce grafiche (GUI)
PREREQUISITI Saper creare file con un editor a caratteri (vi, emacs, etc.) Saper realizzare programmi in ambiente compilativo (C, C++, PASCAL, etc.) Saper navigare in Internet con un browser orientato alla GUI (Netscape, Explorer, etc.)
JAVA E' UN LINGUAGGIO... sviluppato da Sun Microsystems in controtendenza rispetto al passato corredato da un ambiente di sviluppo portabile su varie piattaforme HW/SW orientato agli oggetti (OO) contenente primitive per CP progettato (anche) per realizzare GUI posizionato per l'editoria su Internet
INDICE Java: un tuffo nel linguaggio e nell'ambiente Introduzione a Java e HotJava Elementi di programmazione object-oriented Linguaggio Java:costrutti di base "La" microapplicazione in Java Trattamento delle eccezioni in Java Multithreading: programmazione concorrente Le applet e lo strumento appletviewer Primitive grafiche e programmazione di GUI
CAPITOLO 1 JAVA: UN TUFFO NEL LINGUAGGIO E NELL'AMBIENTE
"LA" MICROAPPLICAZIONE class Hello { public static void main (String args []) { System.out.println("Hello World!"); }} Creare il file:Hello.java Compilarlo:javac Hello.java Si ottiene il file:Hello.class Interpretarlo:java Hello L'output è:Hello World!
SPIEGAZIONI public static void main (String args []) –public rende il codice visibile al comando java (interprete) –static rende main invocabile anche in assenza di istanze della classe Hello (main è un attributo della classe Hello piuttosto che delle sue singole istanze) –void indica che main non ritorna nulla, il che è necessario per superare il type-checking del compilatore –args[] sono gli argomenti passati a main dalla shell quando si digita: java Hello arg1 arg2... argn System.out.println("HelloWorld!") –invoca il metodo println dell'oggetto out della classe System, che stampa la stringa sul file stdout
APPLET Miniapplicazione Java progettata per essere eseguita "all'interno di un (Web) browser" Viene attivata dall'interno di un file HTML con..... AlternateContent Deve essere dichiarata come estensione della classe Applet public class HelloApp extends Applet {..... }
LO STRUMENTO appletviewer E' un "minibrowser" per file HTML: consente di creare ed eseguire applet in assenza di un browser vero e proprio (e.g. Mosaic, HotJava, Netscape, Explorer, etc.) Crea una finestra di browsing comprendente un oggetto grafico (classe Graphics) a sua volta comprendente un'area grafica entro la quale operano le primitive di I/O (sia grafiche che alfanumeriche) invocate dalla applet Oltre ai metodi della classe Applet, fornisce (nella GUI) un menu per controllare la applet
ESEMPIO DI APPLET Nel file HelloApp.java inserire il codice import java.applet.Applet; import java.awt.Graphics; public class HelloApp extends Applet { public void paint (Graphics g) { g.drawString("Hello world!", 25, 25); } Compilare con javac ottenendo HelloApp.class
USO DI appletviewer Nell'ambiente shell, è sufficiente digitare appletviewer [-debug] URL/file..... I tag diversi da presenti nei vari URL/file vengono semplicemente ignorati Per ciascun tag si genera una finestrella corredata da un menu Applet Ciascuna applet esegue le operazioni di I/O nella finestrella di propria competenza L'utente può controllare l'esecuzione della applet selezionando funzioni dal menu Applet
ESEMPIO DI ATTIVAZIONE DI APPLET VIA appletviewer Nel file HelloApplet.html inserire il codice Per attivare la applet digitare il comando appletviewer HelloApp.html e poi operare con il menu Applet della finestra
IL MENU Applet DI appletviewer Restart - esegue stop() seguita da start() Reload - esegue stop() e destroy() e ricarica la applet (se ricompilata, ne carica la nuova versione) Tag- mostra il tag che ha generato la applet Clone- crea e avvia una nuova istanza della applet in una nuova finestra appletviewer Info - mostra informazioni presenti nel file HTML Properties- finestra di dialogo: consente di configurare i parametri di sicurezza e di accesso alla rete Close- usa destroy() per terminare la applet e, se non ve ne sono altre, termina appletviewer Quit- chiude tutte le applet e termina appletviewer
JAVA E IL WEB DI INTERNET HTML/WWW si limitano alla presentazione statica di testo e grafica con modalità ipertestuale in ambiente di rete Java/HotJava estendono i servizi di rete alla presentazione di informazione multimediale (suono, video) e all'attivazione di programmi grafici e non
CAPITOLO 2 INTRODUZIONE AL LINGUAGGIO JAVA E ALL'AMBIENTE HOTJAVA
IL LINGUAGGIO JAVA Semplice ed estensibile (OO) Distribuito Interpretato Robusto Sicuro Architetturalmente neutrale Portabile A elevate prestazioni Concorrente (multithreaded) Dinamico
SEMPLICE/ESTENSIBILE (OO) Sintassi simile a C e C++ (facile da imparare) Elimina i costrutti più "pericolosi" di C e C++ –aritmetica dei puntatori –strutture (struct) –definizione di tipi (typedef) –preprocessore (#define) –(de)allocazione esplicita della memoria Aggiunge garbage collection (GC) automatica Conserva la tecnologia OO di base di C++ Rivisita C++ in alcuni aspetti (W.Joy: C++--==) Interprete completo occupa 215 KB di RAM
DISTRIBUITO E NEUTRALE Incorpora molte funzionalità di rete (TCP/IP) Comprende librerie di livello superiore (HTTP) Rete facilmente accessibile (come i file locali) Compilatore produce codice di tipo byte-code Byte-code indipendente da architettura HW Codice eseguibile su molte piattaforme HW Sviluppo: Solaris (SPARC), Win95 e NT (Intel) Disponibilità: le principali piattaforme HW/SW
FLUSSO DEL CODICE Compilatore Byte-code Java Rete Piattaforma hardware Loader delle classi Interprete Ambiente a run-time Verifica del byte-code Generatore di codice Sorgente Java
ROBUSTO Rilevamento errori (compile-time e run-time) Type-checking (compile-time e run-time) Mascheramento dei puntatori all'utente Impossibilità di fare "casting" di puntatori Controllo automatico dei puntatori nulli Controllo automatico degli indici degli array Gestione delle eccezioni da parte dell'utente Verifica del byte-code prima dell'esecuzione Gestione della memoria (allocazione & GC)
SICURO Dimostratore della correttezza del byte-code Rispetto garantito dei limiti dello stack Correttezza dei parametri delle istruzioni Legalità dell'accesso ai campi degli oggetti –pubblici –privati –protetti Legalità di tutte le conversioni di tipo In particolare, impossibilità di convertire numeri a puntatori, etc.
PORTABILE, INTERPRETATO E A ELEVATE PRESTAZIONI Formato dei dati specificato nei dettagli (p.es. gli interi sono di 32 bit e in complemento a 2) Primitive grafiche astratte facilmente portabili agli ambienti Unix, Windows e Macintosh Interpretazione abbrevia il ciclo di sviluppo Circa funcalls/sec (SPARCstation10) Traduzione a run-time di byte-code in codice macchina fornirà prestazioni simili a C e C++
CONCORRENTE E DINAMICO Multithreading parte integrante del linguaggio Applicazioni interattive più facili a scriversi Migliore "reattività" (anche se non real-time) Esempio: caricamento asincrono di immagini nei browser di rete riduce i tempi di attesa Codice eseguibile anche in assenza di moduli Nuove release di moduli usabili a parità di API Nuovi protocolli caricabili da rete (download) Browser non più "centralisti" ma "federalisti"
BROWSER "FEDERALISTA" Client:richiesta oggetto da parte utente Rete:trasferimento richiesta al server Server:reperimento oggetto nel database Rete:trasferimento oggetto al client Client:rilevamento oggetto di tipo ignoto Rete:trasferimento informativa al server Server:reperimento codice Java adeguato Rete:trasferimento codice Java al client Client:visualizzazione oggetto richiesto
L'AMBIENTE HOTJAVA Browser abilitato all'impiego di Java Manipola URL tradizionali Decodifica pagine HTML tradizionali Attiva programmi Java riferiti da pagine HTML Programmi Java attivabili non solo via HTML Quasi tutti i browser oggi sono Java-enabled Gli altri browser ignorano i link a oggetti Java
CAPITOLO 3 ELEMENTI DI PROGRAMMAZIONE OBJECT-ORIENTED
PROBLEMI DEL SOFTWARE Quantità sempre maggiori (informatizzazione) Sempre più complesso (e struttura non ovvia) Difficile da specificare (redazione "capitolati") Difficile costruirne di affidabile (robustezza) Difficile da collaudare (esaustività dei test) Difficile rimozione dei guasti (manutenibilità) Soggetto a continue modifiche (evoluzione) Modello di produzione "diffusa" (integrazione) Intrattabile con metodologie "centralistiche"
OGGETTI: CHE SONO MAI? Versione informatica degli oggetti "reali" Dotati di una loro propria "individualità" Capaci di interagire per scambio di messaggi Caratterizzati da proprietà (dati e funzioni) Data abstraction: proprietà "statiche" (stato) Functional abstraction: proprietà "dinamiche" (astraggono il "comportamento" dell'oggetto) Un msg modifica stato e attiva comportamenti Un oggetto "è" una coppia [stato,funzioni]
ESEMPIO: UN'AUTOMOBILE Functional abstraction –Avvìati –Férmati –Gira a destra –Gira a sinistra Data abstraction –Colore –Velocità –Rotazione volante –Livello carburante –Ultima revisione
INCAPSULAMENTO Associazione oggetto-coppia [stato,funzioni] Permette di "nascondere" aspetti della coppia Alcuni attributi sono visibili "all'esterno" Altri attributi sono "privati" dell'oggetto Le parti private sono reimplementabili senza implicazioni per gli interlocutori dell'oggetto Propagazione delle modifiche assai contenuta Stimolo al riutilizzo di oggetti ("black-box") Nascita di un'industria di componenti SW
ESEMPIO: AUTOMOBILE Parti "visibili" (interfaccia pubblica): accesso a "ciò che l'auto può fare" –volante, combinazione volante-freno (ev. a mano) –blocchetto di accensione, oppure manovella –pedale dell'acceleratore, acceleratore automatico Parti "nascoste" (implementazione): "come l'auto fa ciò che si può fare" –meccanica dello sterzo e dell'alimentazione –elettromeccanica dell'avviamento –sistema di alimentazione e accensione
(IN)VISIBILITA' E PUREZZA L'implementazione può essere cambiata a parità di interfaccia pubblica –presenza o meno del servosterzo –motorino di avviamento o piccola carica di dinamite –accensione elettromeccanica o elettronica Approccio "puro": lo stato è privato, e lo si può modificare solo attraverso l'uso di quelle componenti funzionali che sono state dichiarate pubbliche (es. "férmati") Approccio di Java: anche le componenti dello stato possono essere dichiarate pubbliche e modificate dall'esterno (es. "velocità=0")
INTERAZIONI TRA OGGETTI Gli oggetti possono comunicare e interagire mediante scambio di messaggi attraverso le loro interfacce pubbliche (stato o funzioni) Per mezzo di un messaggio un oggetto può chiedere un'informazione a un altro oggetto, causarne un cambiamento di stato, oppure delegargli un'attività Un messaggio in arrivo viene trattato dal metodo omonimo del ricettore, il quale "si attiva" per rispondere, per cambiare di stato, oppure per intraprendere un'attività
ESEMPIO: UN'AUTOVETTURA Il sistema antiskid durante una frenata invia periodicamente un messaggio alle ruote per "leggere" la loro velocità di rotazione Il galleggiante nel serbatoio del carburante invia messaggi all'indicatore di livello sul cruscotto per "scrivervi" un nuovo stato Il volante tornando alla posizione di riposo invia un messaggio al comando meccanico dell'indicatore di direzione per delegargli il compito di interrompere l'eventuale segnale lampeggiante (i.e. di "togliere la freccia")
CLASSI Visione "naturalistica" più che "insiemistica": insiemi di oggetti (gli esemplari della classe) aventi identica struttura (stato composto di identici attributi, identico comportamento) Specificano sia le componenti dello stato (nome e tipo, ma non necessariamente il valore) che le operazioni possibili (non solo nome e tipo, ma anche il comportamento) Due esemplari di una stessa classe sono distinguibili solamente per il valore dei loro attributi (il comportamento è sempre identico)
SOTTOCLASSI E SOPRACLASSI Sono rispettivamente la specializzazione e la generalizzazione di una classe per variazione del numero dei membri e/o per loro modifica Una sottoclasse si ottiene per aggiunta, per occultamento o per ridefinizione di uno o più membri rispetto alla classe di partenza (che diventa una sopraclasse della nuova classe) Gli oggetti della sottoclasse non "sanno" se sono nativi o se sono derivati da sopraclassi NOTA BENE: in funzione del problema, sono possibili più tassonomie diverse, così come avviene nelle scienze naturali
ESEMPIO: L'AUTOMOBILE La classe "automobile" è generalizzabile alla sopraclasse "veicolo a motore", a sua volta generalizzabile alla sopraclasse "veicolo", a sua volta, generalizzabile alla classe "mezzo di trasporto", a sua volta... (omissis)... a sua volta generalizzabile alla classe "oggetto" Oppure è specializzabile alla sottoclasse "berlina", a sua volta specializzabile alle sottoclassi "segmento A", "segmento B", etc. Alternativamente, la classe "berlina" può essere specializzata alle sottoclassi "diesel", "a benzina", "elettrica", "a reazione", etc.
EREDITARIETA' E' il meccanismo di specializzazione che consente di derivare una sottoclasse (N.B.: non una sopraclasse!) da una classe data Consente quindi il "riutilizzo programmabile" Le componenti della classe originale vengono conservate nella classe derivata, a meno che in quest'ultima non vengano esplicitamente occultate (p.es. perché ritenute irrilevanti o "dannose") o ridefinite (p.es. perché se ne può fornire un'implementazione migliore) Alle componenti della classe data se ne possono aggiungere altre a piacimento
ESEMPI: GUI, MATRICI E 740 Implementazione di un'interfaccia grafica –classe "finestra": attributo privato "sfondo" e metodo "cambia-sfondo" –sottoclasse "finestra-nera": attributo privato "sfondo" ridefinito con il valore costante "nero", metodo "cambia- sfondo" occultato Libreria di algebra lineare: –classe "matrice": metodo "determinante" generico –sottoclasse "matrice-diagonale": metodo "determinante" che moltiplica tra di loro gli elementi sulla diagonale Compilatore della dichiarazione dei redditi –classe "contribuente": quadri del modello 740 base –classe "autonomi": aggiunta del membro "quadro-E"
EREDITARIETA' MULTIPLA Insieme di meccanismi (la letteratura non è univoca) che consentono di derivare nuove sottoclassi da due o più (sopra)classi Esempio: due resistenze in serie possono essere viste come esemplare della classe "circuito" (o magari "circuito-serie-parallelo") o come esemplare della classe "resistenza" Porzioni di codice diverse possono scegliere di trattare un oggetto secondo l'una o l'altra "vista", specificando qual'è la scelta corrente Java non implementa ereditarietà multipla
"NANETTO" DI PAOLO ERCOLI Al chiar.mo prof. Paolo Ercoli Direttore del Centro di Calcolo Sede Roma, Caro Ercoli, nella mia qualità di presidente del corso di laurea in Ingegneria Informatica mi trovo a lamentare il disservizio... (omissis)... Con i migliori saluti. Paolo Ercoli
CLASSI ASTRATTE Create per generalizzazione, rappresentano descrizioni "incomplete" di oggetti Raccolgono alcune delle loro caratteristiche comuni, ma non in quantità sufficiente a farne delle vere e proprie superclassi Pertanto non posseggono esemplari ("non possono essere istanziate"), ma è possibile derivarne sottoclassi "vere" (i.e. non astratte) Usate principalmente come strumenti di polimorfismo per definire operazioni (e.g. "print") comuni a più classi poco correlate
TERMINOLOGIA E SINONIMI Classi o tipi –generalizzazione, specializzazione o raffinamento –sottoclasse o figlia, sopraclasse (o superclasse) o madre o classe base, classe astratta –ereditarietà [ingl. "inheritance"], gerarchia o tassonomia di classi Oggetti o attori –esemplare [gerg. "istanza", da "instance"] di una classe –componente o membro o proprietà Funzioni o operazioni –astrazione funzionale o comportamento (behaviour) –componente pubblica o interfaccia o metodo Dati o attributi –stato [il termine "data abstraction" è mal traducibile]
CAPITOLO 4 LINGUAGGIO JAVA: COSTRUTTI DI BASE
ALFABETO Java adotta la codifica standard Unicode della società Unicode, Inc. (ftp://ftp.unicode.org) definito in: The Unicode Standard, Worldwide Character Encoding, Version 2.0 I programmi Java possono essere scritti con altre codifiche (e.g. la codifica ASCII a 7 o 8 bit), ma devono essere convertiti alla codifica Unicode (a 16 bit) prima di essere utilizzati da parte di compilatori, interpreti, debugger, etc. N.B. - Nello standard Unicode, un segmento della codifica è riservato ai caratteri speciali
CODICE SORGENTE Consiste di una o più unità di compilazione Ogni unità può contenere (oltre ai commenti) –al più una istruzione package –una o più istruzioni import –una o più dichiarazioni di classe (class) –una o più dichiarazioni di interfaccia (interface) Per ciascuna unità di compilazione, al più una classe può essere dichiarata public Il codice sorgente viene compilato a bytecode (cfr. The Java Virtual Machine Specification), un insieme di istruzioni machine-independent
COMMENTI Presenti in tre diversi stili, non hanno alcuna influenza sulla semantica dei programmi –// Primo stile: io sono un commento su di una sola linea –/* Secondo stile: anch'io sono un commento monolinea */ –/* Secondo stile: io, invece, sono un commento più lungo: non ci sto in una sola linea e quindi ne occupo ben due */ –/** Terzo stile: io sono un commento di tipo speciale, che chiamano "commento di documentazione". */ Un commento del terzo tipo va collocato solo immediatamente prima di una dichiarazione (di classe, di interfaccia, di costruttore o di membro); viene incluso nella documentazione generabile automaticamente (ex sorgente)
TIPI SEMPLICI "Non tutti i dati sono oggetti" (impurità di Java) boolean- tipo enumerativo (due elementi) char- carattere di 16 bit (Unicode 1.1.5) byte- intero di 8 bit (complemento a 2) short- intero di 16 bit (complemento a 2) int- intero di 32 bit (complemento a 2) long- intero di 64 bit (complemento a 2) float- floating-point di 32 bit (IEEE 754) double- floating-point di 64 bit (IEEE 754) Tutti i tipi semplici (o di base) sono predefiniti
TIPI COMPOSTI Equivalenti alle variabili strutturate PASCAL, nella loro versione dinamica (operatore new) I dati composti sono mediati, i.e. manipolati per mezzo di puntatori non visibili all'utente (i dati semplici sono immediati, i.e. manipolati direttamente) Tre categorie di tipi composti –Matrici- versione dinamica degli array PASCAL –Classi- versione "attiva" dei record PASCAL –Interfacce- simili alle dichiarazioni forward in PASCAL Di questi, solo i tipi matrice sono predefiniti: le librerie di classi e di interfacce non lo sono
LETTERALI (1) Rappresentazione "esterna" di dati e oggetti Alcuni tipi semplici ammettono letterali –boolean- true, false –char- 'a', '\u03ff', '\037', '\x7f' - '\', '\n', '\t', '\b', '\r', '\f', '\\', '\'', '\"' –int- 127, 0177, 0x7F, 0X7F, 0x7f, 0X7f –long- 127L, 127l, –float- 3.14, 3.1E12, 3.1e-12,.1e12, 2e-12 –double- 3.14D, 3.14d, 3.1e-12D,.1e12d, 2e-12D Uno solo dei tipi composti ammette letterali –String- "", "Da\ncapo", "Io non sono Luigi Stringa" Per gli altri esiste il letterale generico null
LETTERALI (2) Letterali distinti possono rappresentare lo stesso valore –int- 127, 0177, 0x7F I numeri negativi, di qualunque tipo siano (salvo gli esponenti), non sono esprimibili mediante letterali Le routine di stampa sono in grado di stampare qualunque dato di tipo semplice Il formato di stampa è coerente con quello dei letterali (se esiste); nel caso di più formati possibili, ne viene scelto uno come standard
PAROLE CHIAVE (RISERVATE) Parole chiave: abstract, boolean, break, byte, case, catch, char, class, const (*), continue, default, do, double, else, extends, final, finally, float, for, goto (*), if, implements, import, instanceof, int, interface, long, native, new, package, private, protected, public, return, short, static, super, switch, synchronized, this, throw, transient (*), try, void, volatile, while (*) Inutilizzata nella specifica attuale di Java
IDENTIFICATORI Debbono iniziare con una lettera (v. sotto) o con uno dei due simboli '_' e '$', e possono contenere qualunque carattere non speciale della codifica Unicode; non hanno (in pratica) limiti di lunghezza Ai fini di Java, sono lettere –tutti i caratteri compresi tra 'A' e 'Z' e tra 'a' e 'z' –le non-cifre di codice Unicode superiore a 00C0 (hex) Esempi: identifier, user_name, User_name, _user_name, $user_name, user$name1 Se attributi di classi, sono inizializzati a false (i boolean), 0 (i tipi numerici) o null (il resto)
MATRICI Vettori monodimensionali di dati, semplici o composti, di tipo omogeneo –Semplici - char a[]; char[] b; char array[]; –Composti (oggetti) - String args[]; String[] other_args; –Composti (matrici) - char chess[][]; char[][] checkers; Voxel human_body[][][]; Indicizzati con int (indice primo elemento = 0), con controllo di validità degli indici a run-time Vanno create e dimensionate esplicitamente, anche contestualmente alla dichiarazione (la quale di per sé non alloca nulla, ma si limita a definire il tipo di un nome, inizializzato a null)
MATRICI: CREAZIONE INIZIALIZZAZIONE Dichiarazione e successiva creazione int array[][];/* qui array == null */ array = new int[10][3]; Dichiarazione e contestuale creazione int array[][] = new int[10][3]; Dichiarazione e parziale creazione int array[][] = new int[10][]; Dichiarazione, creazione e inizializzazione –String names[] = {"Tic","Tac"}/* equivalente a... */ –String names[] = new String[2]; names[0] = "Tic"; names[1] = "Tac";
ERRORI CON LE MATRICI Tentare di dimensionare una matrice nella (e non contestualmente alla) sua dichiarazione int list [50]; Tentare di inizializzare una matrice prima di averla creata int list[]; for (int i=0 ; i<9 ; i++) { list[i] = i; } Prima della sua creazione (operatore new) la matrice non esiste: la dichiarazione ha l'unico scopo di specificare il tipo della variabile (che comprende solo il numero delle dimensioni)
MATRICI COME CLASSI Dalla classe Object, la capostipite di tutte le classi, deriva la classe Array, dotata di un metodo length ereditato dalle sue sottoclassi int a[][] = new int[10][3]; a.length;/* 10 */ a[0].length;/* 3 */ Per ogni tipo (semplice o composto) esiste implicitamente una sottoclasse di Array che comprende tutte le matrici di oggetti di quel tipo (N.B. da Array non si possono derivare sottoclassi esplicitamente) Se B è sottoclasse di A, allora B[] lo è di A[]
CLASSI, ATTRIBUTI E METODI Esempio di classe public class MyClass { int i; /* attributo */ public MyClass () { /* metodo costruttore: ha lo i = 10; stesso nome della classe */ } public void Add_to_i (int j) { /* altro metodo */ i = i+j; } Ricordiamo che Java non adotta il modello a oggetti puro: "non tutti i dati sono oggetti"
FUNZIONI E POLIMORFISMO: OVERLOADING DI METODI Variante dell'esempio precedente public class MyNewClass { int i; /* attributo */ public MyNewClass () { /* metodo costruttore: ha lo i = 10; stesso nome della classe */ } public MyNewClass (int j) { /* altro metodo costruttore i = j; diverso dal precedente */ }..... } Metodi omonimi devono essere distinguibili per la quantità e/o per il tipo degli argomenti
ATTRIBUTO this Implicitamente presente in ogni oggetto, è sempre legato all'oggetto medesimo public class MyNewClass { int i; /* attributo */ public MyNewClass () { i = 10; } public MyNewClass (int i) { /* parametro */ this.i = i; /* disambiguazione */ }..... } Risolve omonimie e.g. tra attributi e parametri
CREAZIONE DI OGGETTI Creazione e uso di un oggetto con MyClass MyClass mc; /* dichiarazione, non creazione */ mc = new MyClass(); /* creazione: l'attributo i vale 10 */ mc.i++; /* ora i vale 11 */ mc.Add_to_i(10); /* e ora i vale 21 */ Creazione di un oggetto con MyNewClass MyNewClass mc0, mc1; /* dichiarazione, non creazione */ mc0 = new MyNewClass(); /* creazione: l'attributo i vale 10 */ mc0.i++; /* ora i vale 11 */ mc1= new MyNewClass(20); /* creazione: l'attributo i vale 20 */ mc1.i++; /* ora i vale 21 */
DISTRUZIONE DI OGGETTI Java non supporta "distruttori" espliciti: gli oggetti non si distruggono, si "riciclano" Un oggetto privo di puntatori incidenti non è più accessibile alle applicazioni e la memoria che esso occupa può essere "riciclata" String s; /* dichiarazione, non creazione */ s = new String ("abc"); /* creazione: s punta a "abc" */ s = "def"; /* "abc" non è più puntata da s */ Il "riciclatore" (garbage collector, o GC) opera in un thread indipendente (i.e. "in parallelo" con altri thread, sia di utente che di sistema)
FINALIZZATORI DI OGGETTI Un oggetto "riciclabile" (i.e. privo di puntatori incidenti) potrebbe trovarsi in uno stato poco "pulito" (e.g. in passato potrebbe aver aperto dei file che non sono stati ancora chiusi) Prima di procedere alla fase cruenta, il GC invoca il metodo finalize di ciascun oggetto "riciclabile", definibile da utente protected void finalize () /* per protected vedi oltre */ { close (); } /*chiudi tutti i file aperti */ Il metodo finalize esiste sempre: se non è stato ridefinito viene ereditato da Object
CLASSI: SINTASSI [Doc comment][Modifiers] class ClassName [extends SuperClassName] [implements InterfaceName [, InterfaceName]] {ClassBody} Doc comment- commento "di documentazione" Modifiers- uno o più dei qualificatori abstract, final, public/protected/private, native, synchronized, transient, volatile extends- la classe è sottoclasse di un'altra (e di una sola: ereditarietà singola) implements- la classe realizza una o più interfacce (può "simulare" ereditarietà multipla) ClassBody- gli attributi e i metodi della classe
CLASSI E SOTTOCLASSI Le zebre come particolari tipi di cavallo... public class Horse { int Head, Tail, Legs, Body; public Horse () { Head = 1; Tail = 1; Legs = 4; Body = 1; } public void AddLegs (int Legs) { this.Legs += Legs;} } public class Zebra extends Horse { int Stripes; public Zebra (int Stripes) { this.Stripes = Stripes; } public void AddLegs (int Legs) /* ridefinizione */ { this.Legs += Legs + Stripes; } }
SOTTOCLASSI E super Manipoliamo le zampe di una nuova zebra Zebra mz; mz = new Zebra( ); /* ha 4 zampe */ mz.AddLegs(4); /* ora ne ha */ Il vecchio metodo AddLegs è ancora usabile mz.super.AddLegs(4); /* ora ne ha */ L'attributo super, implicitamente presente in ogni oggetto, permette di "ricuperare" un attributo/metodo da una (sopra)classe dopo che è stato ridefinito in una sua (sotto)classe
SOTTOCLASSI E CASTING Proseguendo con l'esempio precedente Horse mh = (Horse)mz; /* ora è vista come cavallo */ mh.AddLegs(4); /* ora ha zampe */ (Zebra)mh.AddLegs(4); /* ora ne ha */ Il cast da una classe a una sottoclasse (anche non diretta) è possibile se l'oggetto è davvero un esemplare della sottoclasse (il controllo è fatto a run-time); il viceversa è sempre OK Il cast per linea di discendenza non diretta è un errore (il controllo è fatto a compile-time) Il cast non altera gli oggetti: influisce solo sul modo di "osservare" un puntatore all'oggetto
METODI: SINTASSI [Doc comment][Modifiers] ReturnType MethodName (ParameterList) {MethodBody} Modifiers- uno o più dei qualificatori abstract, final, public/protected/private, native, synchronized, transient, volatile ReturnType- va omesso nei costruttori, ma va indicato (eventualmente void) negli altri casi; deve essere identico al tipo ritornato da metodi sovrascritti ParameterList- deve essere coerente con quella dei metodi sovrascritti MethodBody- le variabili locali devono essere inizializzate prima di essere usate
ACCESSI E CONDIVISIONE Quattro tipi di diritti d'accesso –publicvoid AnyOneCanAccess() {... } –protectedvoid OnlySubclassesCanAccess() {... } –privatevoid NoOneElseCanAccess() {... } – void OnlyFromWithinMyPackage() {... } L'ultimo tipo si chiama "friendly" Attributi statici: condivisi da tutte le istanze; metodi statici: operano solo su dati statici class NewDocument extends Document { static int Version = 10; int Chapters; static void NewVersion () { Version++; } /* OK */ static void AddChapter () { Chapters++; } } /* KO */
TIPI DI CLASSE Quattro tipi di classi –abstract: tra i vari metodi, deve contenerne almeno uno abstract, ma non può contenere metodi private o static; deve dare origine a sottoclassi; non può essere istanziata –final: termina una catena di classi-sottoclassi, non può dare origine a ulteriori sottoclassi –public: può essere usata senza formalità nel package che ne contiene la dichiarazione; disponibile anche in altri package, purché vi venga "importata" –synchronized: tutti i metodi interni sono synchronyzed Classi astratte public abstract class Graphics { /* generica */ public abstract void DrawLine(int x1,y1,x2,y2); } public class VGA extends Graphics { /*specifica */ public void DrawLine(int x1,y1,x2,y2) { }}
INTERFACCE Alternativa alle classi astratte: non richiede la derivazione esplicita di sottoclassi public interface AudioClip { void play ();/* avvia i'esecuzione */ void loop ();/* esegui ciclicamente una audio clip */ void stop (); }/* interrompi l'esecuzione */ class MyAudio implements AudioClip { void play () { } void loop () { } void stop () { } } class YourAudio implements AudioClip { } I metodi possono essere public o abstract, gli attributi public, static o final
OPERATORI E PRECEDENZA Operatori (ordine di precedenza decrescente):. [] () ! ~ instanceof * / % + - /* anche: String name = "Luigi" + "Stringa" */ > >>> = == != /* ritornano un booleano */ & ^ | && || ?... :... = += -= *= /= &= |= ^= %= >= >>>=
ISTRUZIONI CONDIZIONALI If –if (boolean) { statements; } else { statements; } Case –switch (expr) { case tag1: statements; break;..... case tagn: statements; break; default: statements; break; }
ISTRUZIONI ITERATIVE For –for (init expr1 ; test expr2 ; incr expr3) { statements; } While –while (boolean) { statements; } Do –do { statements; } while (boolean) Controllo di flusso –break [label] –continue [label] –return expr; –label: statement
FOR, SWITCH, CONTINUE E BREAK: PRECISAZIONI label: for (int i =0, int j=0 ; i<10 && j<20; i++, j++) { /* exp */ for (int z=0 ; z<100 ; z++) { /* scope è solo il for */ switch (expr) { case tag: statements; break; /* prosegue con penultima riga */..... default: statements; break label; } /* prosegue da label */ if (z==15) continue; /* prosegue il for z */ if (z==i+j) continue label; /* prosegue da label */ }
CAPITOLO 5 "LA" MICROAPPLICAZIONE: COME LA SI SCRIVE IN JAVA
"LA" MICROAPPLICAZIONE class Hello { public static void main (String args []) { System.out.println("Hello World!"); }} Creare il file:Hello.java Compilarlo:javac Hello.java Si ottiene il file:Hello.class Interpretarlo:java Hello L'output è:Hello World!
SPIEGAZIONI public static void main (String args []) –public rende il codice visibile al comando java (interprete) –static rende main invocabile anche in assenza di istanze della classe Hello (main è un attributo della classe Hello piuttosto che delle sue singole istanze) –void indica che main non ritorna nulla, il che è necessario per superare il type-checking del compilatore –args[] sono gli argomenti passati a main dalla shell quando si digita: java Hello arg1 arg2... argn System.out.println("HelloWorld!") –invoca il metodo println dell'oggetto out della classe System, che stampa la stringa sul file stdout
ERRORI DI COMPILAZIONE E DI ESECUZIONE javac: Command not found –la variabile path della shell non include la directory in cui si trova il compilatore javac (analogamente per java) System.out.printl ("HelloWorld!) ^ –errore di stumpa:il metodo si chiama println, non printl In class Hello: main must be public and static –ci si è dimenticati di dichiarare main come static Can't find class Hello –errore di stumpa: nel file Hello.java la classe è stata dichiarata erroneamente p.es. con il nome di Helllo, e il compilatore ha creato un file di nome Helllo.class, che l'interprete non può trovare se si è digitato: java Hello
PACKAGE E DIRECTORY Alcuni package disponibili con il JDK –java.applet: classe Applet e tre interfacce (AppleContext, AppleStub, AudioClip) –java.awt: widgets per creare GUI (classi Graphics, Button, Choice, Menu, Component, Panel, TextArea, TextField) –java.io: classi di I/O (FileInputStream, FileOutputStream) –java.lang: classi base del linguaggio (Object, Thread, Exception, System, Integer, Float, Math, String, etc.) –java.net: classi a supporto delle applicazioni di rete (Socket, URL, URLConnection) –java.util: classi miste (Date, Dictionary, Random, Stack) Il package java.packagename si trova nella directory java/packagename, e in essa vi si trovano i file con le classi (Classname.class)
PACKAGE E IMPORTAZIONI E' necessario importare le classi che si intendono utilizzare: –import java.util.Date (la sola classe Date del package java.util, che si trova nel file java/util/Date.class) –import java.awt.* (tutte le classi del package java.awt, ossia tutti i file java/awt/*.class) Se un file di nome nome.java contiene la linea package nome1.....nomen il compilatore ne mette il codice eseguibile nel file di pathname nome1/.../nomen/nome.class, altrimenti lo mette nella stessa directory del file sorgente (il package di default, senza nome) e la classe può essere importata con import nome
CAPITOLO 6 LA GESTIONE DELLE ECCEZIONI IN JAVA
ECCEZIONI E catch/throw Consentono di realizzare goto non locali void GrowZebra(Zebra mz) { try { for (;;) {FeedZebra(mz, new Anchovy()) ;}} catch (JunkFoodException e) { mz.Starve(); } catch (ThrowUpException e) { mz.Drink(new Digestive()); } } void FeedZebra(Zebra z, Anchovy a) { Exception away = new JunkFoodException(); Exception up = new ThrowUpException(); if (a.smells()) { throw away; } else if (z.full()) { throw up; } else { z.GiveAnchovy(a); } }
ECCEZIONI PREDEFINITE E DEFINIZIONE DI ECCEZIONI Eccezioni predefinite e ricuperabili ArithmeticException IllegalArgumentException ArrayStoreException IllegalMonitorStateException ClassCastException IllegalThreadStateException NullPointerException IndexOutOfBoundException NumberFormatException NegativeArraySizeException SecurityException Definizione di nuove eccezioni ricuperabili class JunkFoodException extends Exception { JunkFoodException() {} }
CAPITOLO 7 JAVA: MULTITHREADING E PROGRAMMAZIONE CONCORRENTE
PROGRAMMAZIONE MULTITHREAD public class Multithread { public static void main (String args[]) { TestThrd t1, t2, t3; t1 = new TestThrd("Din"; (int)(Math.random())*2000); t2 = new TestThrd("Don"; (int)(Math.random())*2000); t3 = new TestThrd("Dan"; (int)(Math.random())*2000); t1.start(); t2.start(); t3.start(); } class TestThrd extends Thread { private String whoami; private int delay; public TestThrd(String s, int d) { whoami = s; delay = d; } public void run() { try { sleep(delay); } catch (InterruptedException e) {} ; System.out.println(whoami) ; } }
CAPITOLO 8 LE APPLET DI JAVA E LO STRUMENTO appletviewer
APPLET Miniapplicazione Java progettata per essere eseguita "all'interno di un (Web) browser" Viene attivata dall'interno di un file HTML con..... AlternateContent Deve essere dichiarata come estensione della classe Applet public class HelloApp extends Applet {..... }
LA CLASSE Applet: RELAZIONI CON LA GERARCHIA JAVA Tre classi intermedie tra Object e Applet java.lang.Object: capostipite di tutte le classi java.awt.Component: metodi per gestire gli eventi e per "disegnare" linee, curve, bottoni, menu, immagini, etc. java.awt.Container: metodi per "raccogliere" oggetti di classe Component in "contenitori" e per gestirne il posizionamento (layout) java.awt.Panel: l'unica non abstract delle tre java.awt.Applet: capostipite di tutte le applet,
LO STRUMENTO appletviewer E' un "minibrowser" per file HTML: consente di creare ed eseguire applet in assenza di un browser vero e proprio (e.g. Mosaic, HotJava, Netscape, Explorer, etc.) Crea una finestra di browsing comprendente un oggetto grafico (classe Graphics) a sua volta comprendente un'area grafica entro la quale operano le primitive di I/O (sia grafiche che alfanumeriche) invocate dalla applet Oltre ai metodi della classe Applet, fornisce (nella GUI) un menu per controllare la applet
METODI USATI DA appletviewer Ereditati da Applet ("vuoti" se non sovrascritti) init()- chiamata dopo il caricamento della applet start()- chiamata quando una applet viene visitata stop()- chiamata quando l'applet va fuori schermo destroy()- chiamata a fine ciclo di vita della applet Ereditati da Component (g di classe Graphics) paint(g)- disegna una scatola grigia nella finestra update(g)- cancella e ridisegna la scatola nella finestra
ESEMPIO DI APPLET Nel file HelloApp.java inserire il codice import java.applet.Applet; import java.awt.Graphics; public class HelloApp extends Applet { public void paint (Graphics g) { g.drawString("Hello world!", 25, 25); } Compilare con javac ottenendo HelloApp.class
USO DI appletviewer Nell'ambiente shell, è sufficiente digitare appletviewer [-debug] URL/file..... I tag diversi da presenti nei vari URL/file vengono semplicemente ignorati Per ciascun tag si genera una finestrella corredata da un menu Applet Ciascuna applet esegue le operazioni di I/O nella finestrella di propria competenza L'utente può controllare l'esecuzione della applet selezionando funzioni dal menu Applet
ESEMPIO DI ATTIVAZIONE DI APPLET VIA appletviewer Nel file HelloApplet.html inserire il codice Per attivare la applet digitare il comando appletviewer HelloApp.html e poi operare con il menu Applet della finestra
IL MENU Applet DI appletviewer Restart - esegue stop() seguita da start() Reload - esegue stop() e destroy() e ricarica la applet (se ricompilata, ne carica la nuova versione) Tag- mostra il tag che ha generato la applet Clone- crea e avvia una nuova istanza della applet in una nuova finestra appletviewer Info - mostra informazioni presenti nel file HTML Properties- finestra di dialogo: consente di configurare i parametri di sicurezza e di accesso alla rete Close- usa destroy() per terminare la applet e, se non ve ne sono altre, termina appletviewer Quit- chiude tutte le applet e termina appletviewer
METODI DI Applet: QUANDO SOVRASCRIVERLI init()- quando si debbano effettuare inizializzazioni particolari e non di pertinenza del costruttore della applet (p.es. qualora si debbano creare dei thread di animazione da avviare più tardi) start()- quando si vogliano avviare/sospendere le stop() attività della applet in funzione della sua esposizione sullo schermo (e.g. per avviare o arrestare i thread di animazione quando la finestra diventa esposta o nascosta) destroy()- quando, dopo l'ultima stop(), la applet debba esser distrutta, ma prima di fare ciò sia utile annullare l'effetto delle inizializzazioni (p.es. per distruggere i thread di animazione, che altrimenti rimarrebbero sospesi per sempre)
DELEGA A NUOVI THREAD DI ATTIVITA' "UNA TANTUM" Per caricare un oggetto di classe AudioClip public void start() {... /*codice specifico per la applet */ if (onceThread == null) { onceThread = new Thread(this); onceThread.start(); } } public void run() {... /*codice specifico per la applet */ if (Thread.currentThread == onceThread) { myAudio = getAudioClip(... ); } Immagini GIF/JPEG caricate da thread separati
DELEGA A NUOVI THREAD DI ATTIVITA' RIPETITIVE public void start() {... /*codice specifico per la applet */ if (loopThread == null) { loopThread = new Thread(this); loopThread.start(); } public void stop() { loopThread = null; } public void run() {... /*codice specifico per la applet */ while (Thread.currentThread == loopThread) {... } }
METODI DI Component: QUANDO SOVRASCRIVERLI paint(g)- quando si debba presentare un pannello più update(g) sofisticato di un rettangolo con fondo grigio import java.awt.*; import java.applet.*; public class GraphicsApplet extends Applet { public void paint(Graphics g) { Dimension r = size(); g.setColor(Color.red); g.drawRect(10, 10, r.width-20, r.height-20); System.out.println ("paint called"); /* va su stdio */ }
PASSAGGIO DEI PARAMETRI DA FILE HTML A CLASSI JAVA public void init() { String fontsize = getParameter("fontsize"); if (fontsize=null) { fontsize=12; } else { fontsize = Integer.parseInt(fontsize); } } Applets can be viewed with Java-powered browsers only
CAPITOLO 9 JAVA: PRIMITIVE GRAFICHE E PROGRAMMAZIONE DI GUI
CLASSE Component E SUE SOTTOCLASSI Non tratta i menu (MenuComponent e derivate) Controlli fondamentali: Button, Checkbox (e CheckBoxGroup), Choice, List, TextField Acquisizione di input da utente: Scrollbar, TextArea Componenti personalizzate: Canvas Frasi esplicative: Label Contenitori: Container con sottoclassi Panel e Window, quest'ultima con sottoclassi Frame, e Dialog (con sottoclasse FileDialog) TextField, TextArea estendono TextComponent
CLASSE MenuComponent E SUE SOTTOCLASSI Sottoclasse diretta della classe Object, in quanto le funzioni dei menu sono spesso limitate dalla piattaforma ospite, e sarebbe poco appropriato derivarli da Component Controlli fondamentali: MenuItem, con sottoclassi CheckBoxMenuItem e Menu Menu di menu: MenuBar, che possono essere inserite solamente in oggetti di classe Frame
EVENTI E LORO CODIFICA Quando l'utente agisce su una componente, viene generato un evento (oggetto di classe Event) che viene passato come argomento al metodo di gestione degli eventi (handleEvent) di quella componente Gli oggetti di tipo Event contengono –oggetto che ha "subito" l'evento –timbratura (istante di occorrenza) dell'evento –tipo dell'evento (bottone del mouse premuto o rilasciato) –coordinate dell'evento (all'interno della componente) –tasto premuto (solo per eventi generati dalla tastiera) –stato dei tasti modificatori (Shift, CTRL, ALT, etc.)
METODI PER LA GESTIONE DI EVENTI E LORO TIPO action(Event.ACTION_EVENT) mouseEnter(Event.MOUSE_ENTER) mouseExit(Event.MOUSE_EXIT) mouseMove(Event.MOUSE_MOVE) mouseDown(Event.MOUSE_DOWN) mouseDrag(Event.MOUSE_DRAG) mouseUp(Event.MOUSE_UP) keyDown(Event.KEY_PRESS) keyUp(Event.KEY_UP) gotFocus(Event.GOT_FOCUS) /* per componenti */ lostFocus(Event.LOST_FOCUS) /* attivabili da KBD */ handleEvent( )
GESTIONE DEGLI EVENTI All'ocorrenza di un evento, il corrispondente oggetto di tipo Event viene passato al metodo handleEvent (ridefinibile da utente), il quale a sua volta invoca il metodo appropriato Il metodo action viene invocato per gestire gli eventi che intressano i controlli fondamentali: trattasi di un livello di astrazione superiore a quello degli elementari (pressioni e rilasci di tasti) Il valore false ritornato da un gestore di eventi richiede che l'evento venga successivamente passato anche al padre della Component
ESEMPIO: OGGETTO PRIVO DI GESTORE SPECIFICO Non esistendo un metodo action per Scrollbar public boolean handleEvent(Event e) { if (e.target instanceof Scrollbar) {... } return super.handleEvent(e); } Ultima riga: cfr. l'uso di super nei costruttori...
LAYOUT MANAGER Controlla dimensioni e posizionamento delle Component contenute in un Container Ogni Container contiene un LayoutManager di default (ma ridefinibile dall'utente) Cinque tipi di LayoutManager predefiniti (BorderLayout, CardLayout, FlowLayout, GridLayout, GridBagLayout) Altri LayoutManager disponibili sulla rete o programmabili direttamente da utente
PRIMITIVE GRAFICHE Metodi principali della classe Graphics drawLine drawRect, fillRect, clearRect draw3DRect, fill3DRect drawRoundRect, fillRoundRect drawOval, fillOval drawArc, fillArc drawPolygon, fillPolygon drawBytes, drawChars, drawString drawImage Non esistono ancora metodi per formati video