La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

18 novembre 20031 I nomi in Java F. Bombi 18 novembre 2003.

Presentazioni simili


Presentazione sul tema: "18 novembre 20031 I nomi in Java F. Bombi 18 novembre 2003."— Transcript della presentazione:

1 18 novembre I nomi in Java F. Bombi 18 novembre 2003

2 2 Le variabili Una variabile è una posizione in memoria alla quale è associato un determinato tipo che può essere o un tipo primitivo o un riferimento Una variabile ha sempre un valore compatibile con il suo tipo Il valore di una variabile può essere modificato da unassegnazione oppure da un operatore di incremento ( ++ ) o decremento ( -- )

3 18 novembre I 7 tipi di variabili Variabile di classe: un campo di una classe con lattributo static Variabile di esemplare: un campo di una classe senza lattributo static Componenti di un array: sono variabili senza nome che vengono create quando si crea un array destinate a contenere i singoli elementi dellarray Parametro di un metodo: nome di una variabile che sarà inizializzata con il valore dellargomento passato al metodo Parametro di un costruttore: come per un metodo Parametro di un gestore di eccezione Variabile locale: variabile dichiarata allinterno di un blocco

4 18 novembre Variabile di classe Una variabile di classe viene creata al momento in cui la classe viene caricata nella memoria della macchina virtuale e in assenza di indicazione contraria viene inizializzata a 0, false o null Di una variabile di classe esiste un solo esemplare condiviso da tutti gli oggetti della classe Luso di variabili di classe è limitato a casi molto specifici ad esempio per costanti simboliche condivise oppure per contare quanti esemplari di una classe sono stati creati o per segnalare ad altri esemplari di una classe che si è invocato un metodo class A { static int vs; public A () {vs++;} … } … A uno = new A(); … A due = new A(); … System.out.println(A.vs);

5 18 novembre Variabili di esemplare Le variabili di esemplare (instance variable) rappresentano il caso più comune di campo di una classe Un nuova variabile di esemplare viene creata ogni volta che si crea un esemplare della classe che la contiene, in assenza di indicazione contraria, le variabili di esemplare sono sempre inizializzate a 0, false o null Un variabile di esemplare cessa di esistere quando loggetto che la contiene non è più indirizzato da un riferimento (lo spazio di memoria è a questo punto soggetto a garbage collection)

6 18 novembre Componenti di un array Le componenti di un array sono variabile senza nome che vengono create al momento della creazione dellarray. 0 falsenull Sono inizializzati a 0, false o null Fare attenzione che se si crea un array di oggetti la creazione dellarray crea solo i riferimenti agli oggetti (inizializzati a null ) e non gli oggetti che dovranno essere esplicitamente creati uno per uno class Coppia { int a; int b;} … Coppia[] v = new Coppia[4]; v[0].a = 25; // null pointer class Coppia { int a; int b;} … Coppia[] v = new Coppia[4]; for(int i=0;i<4;i++) v[i] = new Coppia(); v[0].a = 25; // OK

7 18 novembre I parametri Un parametro attribuisce un nome allinterno di un metodo allargomento con il quale il metodo viene invocato Un parametro, analogamente ad una variabile locale, viene creato al momento dellinvocazione del metodo e cessa di esistere quando si conclude il blocco che costituisce il corpo del metodo Un parametro viene inizializzato con il valore dellargomento usato al momento della chiamata del metodo Java di conseguenza utilizza sempre e solo il passaggio dei parametri per valore class A { void m(int i) { int locale; locale = i*i; } … A x = new A(); int k = 25; x.m(k); x.m(3); parametro argomento i = k = 25

8 18 novembre static void scambia (int x, int y) { int tmp = x; x = y; y = tmp; } static void scambia (Integer x, Integer y) { Integer tmp = x; x = y; y = tmp; } static void scambia (MioInt x, MioInt y) { int tmp = x.valore; x.valore = y.valore; y.valore = tmp; } class MioInt { int valore; public String toString() { return Integer.toString(valore); } } // Il passaggio dei parametri in Java public class Param { public static void main (String[] arg) { int i = 1; int j = 2; System.out.println("Prima: i= " + i + " j= " + j); scambia(i, j); System.out.println("Dopo1: i= " + i + " j= " + j); Integer ii = new Integer(i); Integer jj = new Integer(j); scambia(ii, jj); System.out.println("Dopo2: i= " + ii + " j= " + jj); MioInt iii = new MioInt(); iii.valore = i; MioInt jjj = new MioInt(); jjj.valore = j; scambia(iii, jjj); System.out.println("Dopo3: i= " + iii + " j= " + jjj); } Il passaggio dei parametri per valore è unidirezionale Prima: i= 1 j= 2 Dopo1: i= 1 j= 2 Dopo2: i= 1 j= 2 Dopo3: i= 2 j= 1

9 18 novembre int i = 1; int j = 2; 1 i 2 j scambia(i, j); static void scambia (int x, int y) { int tmp = x; x = y; y = tmp; } ? x ? y inizializza ? tmp al ritorno del metodo scambia le variabili i e j sono immutate

10 18 novembre Integer ii = new Integer(1); Integer jj = new Integer(2); ii jj scambia(ii,jj); inizializza x y al ritorno del metodo scambia i riferimenti ii e jj sono immutati 1 2 static void scambia (Integer x, Integer y) { Integer tmp = x; x = y; y = tmp; } tmp

11 18 novembre Valore ? jjj Valore ? iii MioInt iii = new MioInt(); iii.valore = 1; MioInt jjj = new MioInt(); jjj.valore = 2; scambia(iii, jjj); al ritorno del metodo scambia i riferimenti iii e jjj non sono cambiati sono però stati scambiati i campi inizializza x y 1 2 tmp static void scambia (MioInt x, MioInt y) { int tmp = x.valore; x.valore = y.valore; y.valore = tmp; } 1 2 1

12 18 novembre Come ritornare un valore Il meccanismo del passaggio dei parametri ad un metodo essendo per valore è unidirezionale, il parametro viene inizializzato con largomento al momento della chiamata, se il parametro viene modificato largomento rimane immutato return Un metodo può restituire una sola variabile con la clausola return, il tipo di valore restituito deve essere indicato nella dichiarazione del metodo

13 18 novembre Uso di variabili globali Allinterno di una classe due metodi possono scambiarsi dati utilizzando un campo della classe come variabile condivisa o globale Questa forma di comunicazione non può essere usata fra metodi di classi diverse in quanto gli esemplari di classi diverse non accedono agli stessi campi parametro implicito Ricordarsi infine che un metodo quando è invocato conosce i campi dellesemplare della classe individuata dal riferimento usato per invocare il metodo detto talvolta parametro implicito this Il valore del parametro implicito è accessibile con la clausola this

14 18 novembre argomento actual parameter parametro reale parametro formal parameter parametro formale allattivazione o chiamata del metodo il valore dellargomento viene utilizzato per inizializzare il corrispondente parametro return valore; Alla terminazione del metodo il controllo viene passato al punto di chiamata. I valore dei parametri vengono persi, in quanto si tratta di variabili locali allocate sul run-time stack (ma non vengono persi eventuali effetti collaterali). Il metodo può restituire un singolo valore

15 18 novembre Pacchetti (package) Una applicazione Java si compone di uno o più pacchetti sottopacchetti Un pacchetto è un insieme di file (unità compilabili), un pacchetto può essere organizzato gerarchicamente in sottopacchetti pacchetto senza nome In assenza di indicazioni contrarie i file contenuti nel directory di lavoro costituiscono un pacchetto senza nome Tutti gli esempi visti a lezione sono realizzati come pacchetti senza nome Abbiamo visto in molti esempi come importare un componente di un pacchetto di libreria o lintero pacchetto

16 18 novembre I nomi in Java nomiidentificatori Tutte le entità usate in un programma Java sono individuate da nomi, dette identificatori, composti da stringhe di caratteri alfanumerici con il primo carattere alfabetico dichiarato Ogni nome deve essere dichiarato prima di essere usato, la dichiarazione specifica lentità cui il nome si riferisce e chi può accedere al nome qualificandolo semplice scope Ogni nome semplice è riconosciuto in una porzione del programma detta il suo scope contesto Il significato di un nome è stabilito dal contesto nel quale viene usato

17 18 novembre Le entità individuate da un nome possono essere – Una classe – Uninterfaccia – Un membro di una classe (campo o metodo) – Un parametro di un metodo, di un costruttore o di un gestore di eccezione – Una variabile locale semplice Un nome semplice è costituito da un solo identificatore qualificato Un nome qualificato è costituito da più identificatori separati da un (punto) public class Coppia implements Comparable { public Comparable chiave; …} public interface Stack { void push (Object x); …} public class Coppia implements Comparable { public Comparable chiave; … public String toString () { return chiave.toString() + ":" + attributo.toString(); } public String toString () { return chiave.toString() + ":" + attributo.toString(); }} public class Coppia implements Comparable { … public Coppia (Comparable c, Object a) { chiave = c; attributo = a; } public Coppia (Comparable c, Object a) { chiave = c; attributo = a; } public int compareTo (Object x) { return chiave.compareTo(((Coppia)x).chiave); } public int compareTo (Object x) { return chiave.compareTo(((Coppia)x).chiave); }} public static void main (String[] arg) throws IOException public static void main (String[] arg) throws IOException { BufferedReader in = new BufferedReader(new FileReader(arg[0])); { BufferedReader in = new BufferedReader(new FileReader(arg[0])); int n = 0; int n = 0; int somma = 0; int somma = 0; … while ((str = in.readLine()) != null) while ((str = in.readLine()) != null) { token = new StringTokenizer(str, ":"); { token = new StringTokenizer(str, ":"); int matricola = Integer.parseInt(token.nextToken()); int matricola = Integer.parseInt(token.nextToken()); String nome = token.nextToken(); String nome = token.nextToken(); dati[n++] = new Studente(nome, matricola); dati[n++] = new Studente(nome, matricola); }

18 18 novembre Lo scope Lo scope di una dichiarazione è la regione di un programma nellambito della quale ci si può riferire ad una entità con il nome semplice Lo scope del nome di una classe è lintero pacchetto nel quale la classe compare Lo scope di un membro di una classe è lintera classe nella quale è dichiarato Lo scope del nome di un parametro di un metodo o di un costruttore è lintero corpo del metodo o del costruttore Lo scope di una variabile locale dichiarata in un blocco si estende fino alla fine del blocco for Lo scope di una variabile locale dichiarata nellinizializzazione di un ciclo for si estende al solo corpo del ciclo public class Coppia implements Comparable { public Object attributo; public Coppia (Comparable c, Object a) { chiave = c; attributo = a; } public Coppia (Comparable c, Object a) { chiave = c; attributo = a; } public int compareTo (Object x) { return chiave.compareTo(((Coppia)x).chiave); } public int compareTo (Object x) { return chiave.compareTo(((Coppia)x).chiave); } public String toString () { return chiave.toString() + ":" + attributo.toString(); } public String toString () { return chiave.toString() + ":" + attributo.toString(); } public Comparable chiave; public Comparable chiave;} int[] r = c.contiene(); int[] r = c.contiene(); for (int i = 0; i < r.length; i++) for (int i = 0; i < r.length; i++) System.out.print(r[i] + ", "); System.out.print(r[i] + ", "); System.out.println(); System.out.println(); c.togli(1); c.togli(1); r = c.contiene(); r = c.contiene(); for (int i = 0; i < r.length; i++) for (int i = 0; i < r.length; i++) System.out.print(r[i] + ", "); System.out.print(r[i] + ", "); System.out.println(); System.out.println(); for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++) if (c.appartiene(i)) if (c.appartiene(i)) System.out.print("1"); System.out.print("1"); else else System.out.print("0"); System.out.print("0");

19 18 novembre Il controllo dellaccesso nomi qualificati Luso di nomi qualificati consente di controllare laccesso ai membri di una classe indipendentemente dallo scope, si danno 4 casi: – default – default: accesso a livello di package – public – public : accesso da qualsiasi punto – private – private : accesso possibile solo dallinterno della classe nella quale il nome è dichiarato – protected – protected : accesso a livello di package e nelle sottoclassi che estendono la classe In genere i campi di una classe sono private (o protected) in quanto si vuole che solo i metodi della classe possano modificare il valore dei campi mentre i metodi sono public perché devono poter essere utilizzati dallesterno della classe

20 18 novembre Oscurare una dichiarazione La dichiarazione di un nome allinterno di un blocco contenuto in un altro blocco può oscurare la dichiarazione più esterna il compilatore non si confonde! In genere è bene evitare di dichiarare la stessa variabile in blocchi diversi con significati diversi per evitare confusione (il compilatore non si confonde! ma il lettore può rimanere confuso) Vediamo ora un esempio di una dichiarazione che ne oscura unaltra in una situazione particolarmente insidiosa

21 18 novembre public class StackAr implements Stack { private Object[] v; private int sp; private int sp; private static final int MAX = 10; private static final int MAX = 10; public StackAr () public StackAr () { sp = 0; { sp = 0; Object[] v = new Object[MAX]; Object[] v = new Object[MAX]; } public StackAr (int max) public StackAr (int max) { sp = 0; { sp = 0; v = new Object[max]; v = new Object[max]; } public void push (Object x) { v[sp++] = x; } public void push (Object x) { v[sp++] = x; } public Object pop () throws Underflow public Object pop () throws Underflow { if (sp == 0) { if (sp == 0) throw new Underflow("Pop di stack vuoto"); throw new Underflow("Pop di stack vuoto"); else else return v[--sp]; return v[--sp]; } public Object testa () throws Underflow public Object testa () throws Underflow { if (sp == 0) { if (sp == 0) throw new Underflow("Testa di stack vuoto"); throw new Underflow("Testa di stack vuoto"); else else return v[sp-1]; return v[sp-1]; } public boolean vuoto () { return sp == 0; } public boolean vuoto () { return sp == 0; }}

22 18 novembre I paradigmi di programmazione Un programma deve essere comprensibile sia al compilatore (e alla macchina) sia alluomo È importante utilizzare paradigmi (modelli) di programmazione che aiutino a scrivere programmi corretti e facili da mantenere e modificare Nel tempo si sono sviluppati molti paradigmi diversi nel tentativo di rendere più facile la produzione di programmi corretti e mantenibili

23 18 novembre La decomposizione funzionale Per decomposizione funzionale si intende la tecnica con la quale si risolve un problema attraverso la composizione di sottoprogrammi o funzioni Ad esempio dovendo leggere ed elaborare dei dati si scrive un sottoprogramma che legge i dati, uno che gli elabora ed un terzo che stampa i risultati Il primo linguaggio che ha messo a disposizione strumenti per facilitare la decomposizione funzionale è stato il Fortran IV (fine anni 50)

24 18 novembre La programmazione strutturata if-then-elsewhile-do Un programma si dice strutturato se è realizzato dalla composizione delle due sole strutture (o loro derivazione) if-then-else e while-do I linguaggi di programmazione moderni (sviluppati dopo linvenzione del Pascal, inizio anni 70) sono per loro natura strutturati e quindi obbligano ad utilizzare naturalmente la programmazione strutturata Lidea è così connaturata con i linguaggi moderni quali il C/C++ o Java che non è quasi più il casi di parlare di programmazione strutturata

25 18 novembre La modularizzazione moduli Per affrontare la costruzione di un grande progetto software è necessario disporre di strumenti che consentano di costruire il software sotto forma di componenti indipendenti detti talvolta moduli Pascal (in origine) non consentiva nessuna forma di modularizzazione, un programma doveva essere sempre pensato come monolitico in quanto doveva contenere al suo interno tutte le procedure e funzioni necessarie macro elaborazione make Il linguaggio C non dispone intrinsecamente di strumenti per la modularizzazione ma non la impedisce, è quindi possibile realizzare in C software modulare utilizzando le funzioni di macro elaborazione fornite dal linguaggio e strumenti esterni quali make per automatizzare le operazioni di espansione delle macro, compilazione e collegamento

26 18 novembre Modularizzazione (segue) I linguaggi Ada e Modula 2 sono stati progettati in modo da facilitare e rendere controllabile la modularizzazione. Hanno però avuto uno sviluppo limitato, il primo solo nellambiente delle commesse militari e spaziali, il secondo solo in un limitato ambiente accademico Alcune estensione del linguaggio C quali C++ e in particolar modo il linguaggio orientato agli oggetti Eifell sono stati pensati in modo da facilitare la modularizzazione

27 18 novembre La programmazione orientata agli oggetti I linguaggio orientati agli oggetti mettono a disposizione una ricco repertorio di strumenti per la realizzazione di software in forma modulare Package Incapsulamento (o information hiding) Polimorfismo Ereditarietà

28 18 novembre Packages -> Pacchetti Un programma in Java è organizzato come un insieme di pacchetti tipi Ogni pacchetto ha un suo insieme di nomi per i tipi (classi e interfacce) tipo public Un tipo dichiarato in un pacchetto è accessibile al di fuori del pacchetto in cui è stato dichiarato solo se ha lattributo public I pacchetti sono organizzati in forma gerarchica come pacchetti e sottopacchetti I pacchetti possono essere memorizzati come file o in un database Lorganizzazione in pacchetti facilita la modularizzazione isolando le scelte dei nomi di un pacchetto da quelle di ogni altro pacchetto

29 18 novembre Incapsulamento incapsulamentoinformation hiding Per incapsulamento o information hiding si intende la caratteristica di un linguaggio che consente di nascondere allutente di un pacchetto (o anche in particolare di una sola classe) i dettagli con cui le funzionalità sono realizzate Java consente di progettare pacchetti e classi in modo da nascondere in modo completo i dettagli realizzativi allutente

30 18 novembre Polimorfismo polimorfismo late binding Il polimorfismo è la proprietà di un linguaggio orientato ad oggetti per cui la decisione di quale metodo viene invocato tramite un riferimento viene stabilito al momento dellesecuzione del programma in funzione del valore effettivamente assegnato al riferimento (in sintesi si parla di late binding) Java è intrinsecamente polimorfo sovraccaricooverloading Una forma elementare di polimorfismo è anche offerta dal sovraccarico (overloading) del nome di un metodo. Notare che il sovraccarico non richiede il late binding in quanto il compilatore può decidere quale metodo invocare dal confronto della forma della chiamata con la firma del metodo (nome e elenco del tipo degli argomenti)

31 18 novembre Ereditarietà Lereditarietà consente di costruire una nuova classe che estende le funzionalità di unaltra classe senza avere accesso al codice sorgente della classe che si vuole estendere Ereditarietà e polimorfismo sono funzionalità da utilizzare in modo coordinato La programmazione orientata ad oggetti si caratterizza dalla possibilità di costruire lestensione di una classe senza disporre del codice sorgente della classe da estendere combinata con la realizzazione del polimorfismo mediante late binding


Scaricare ppt "18 novembre 20031 I nomi in Java F. Bombi 18 novembre 2003."

Presentazioni simili


Annunci Google