Astrazione di dati Dati Astratti: cosa e perchè Dati Astratti: due meccanismi differenti Dati Astratti: due meccanismi differenti Astrazione e incapsulamento.

Slides:



Advertisements
Presentazioni simili
Astrazioni Polimorfe e Tipi Generici. 2 Polimorfismo Dal Greco molte forme Una variabile polimorfa può riferirsi a oggetti di classi diverse Un metodo.
Advertisements

Programmazione object oriented in C++
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
29 febbraio 2008 Progettare tipi di dato astratti.
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
MultiSet, Liste Ordinate
Le gerarchie di tipi.
Esercitazione Frame. Argomento Realizzazione di un tipo di dato astratto Usare le eccezioni per segnalare situazioni particolari Invariante e funzione.
LIP: 19 Aprile Contenuto Soluzione Compitino Tipo di dato MultiSet, estensione con sottoclasse.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Introduzione al linguaggio C++ 5 lezioni
Esercizi su code Date due code in ingresso a valori interi in ordine crescente, scrivere una funzione che restituisca una terza coda che contenga i valori.
1 Le gerarchie di tipi. 2 Supertipi e sottotipi 4 un supertipo –class –interface 4 può avere più sottotipi –un sottotipo extends il supertipo ( class.
Java base IV: Java e la programmazione O.O.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Astrazione procedurale ed eccezioni
Le variabili in Java Nella programmazione tradizionale, una variabile è una porzione di memoria in cui è immagazzinato un certo tipo di dato. Per esempio.
Polimorfismo Significato Significato Varie famiglie Varie famiglie Polimorfismo in java Polimorfismo in java Polimorfismo di Sottotipo: Apparato in Java.
Programmazione ad oggetti
1 Un esempio con iteratore: le liste ordinate di interi.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
1 Osservazioni Generali Struttura di programma Gerarchia di classi: overloading, overriding, e dispatching Analisi ed esecuzione Modificabilità e condivisione.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 non vogliamo definire versioni differenti dell’astrazione corrispondente ad una collezione di elementi.
Astrazione di dati Esercizio 1. Si completi l’implementazione Poly.add data a lezione con la specifica e l’implementazione degli ausiliari min e max data.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Liste di Interi Esercitazione. Una variante Liste concatenate di Integers Non modificabile Costruttori per creare la lista vuota o un nodo Metodi d’istanza.
Primo Compitino Primo esercizio Identificare gli errori segnalati dal compilatore Verifica statica del codice Regole di binding per i nomi (quelle.
Ripasso su Java. Introduzione Per risolvere problemi complessi, i linguaggi di programmazione forniscono costrutti per realizzare nuove funzioni che trasformino.
Liste di Interi Esercitazione. IntList Lista di interi Problema tipico: memorizzare una sequenza di valori [6,0,9,3….9] Vediamo un tipo di dato utile.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
1 Gerarchie e polimorfismo: liste. 2 Generalizzare le liste di interi  List 4 lista di oggetti –non modificabile 4 vorremo poi definire un sottotipo.
1 Laboratorio di Introduzione alla Programmazione §II MODULO §3 crediti §Esame e voto unico (su 6 crediti totali)
1 Astrazione sul controllo: gli iteratori. 2 Gli iteratori 4 perché vogliamo iterarare “in modo astratto” 4 iteratori e generatori in Java –specifica.
LIP: 9 Maggio Esercizi Riprendiamo un esercizio proposto Definire un tipo di dato Persona che definisce oggetti che rappresentano le informazioni.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
1 Un esempio: le liste ordinate di interi. 2 Liste ordinate  OrderedIntList 4 lista ordinata di interi –modificabile.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Metodologie di Programmazione Esercizi sulla semantica di Java.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
Ese 3 (del 31 Marzo 2004). Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare.
Esercizio 3. Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare i commenti.
LIP: 2 Maggio 2008 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Esercitazione. Problema Vogliamo definire in modo gerachico un tipo di dato che definisce Tabelle multi-dimensionali con un numero di righe variabili.
Primo Compitino Terzo Esercizio Implementare il tipo di dato astratto Table un oggetto di tipo Table ha due colonne e un numero variabile di righe.
Progettare una classe 21 Febbraio La classe BankAccount Vogliamo realizzare una classe i cui oggetti sono dei semplici conti bancari. * Identifichiamo.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Metodologie di Programmazione = decomposizione basata su astrazioni.
Ese 1 e 3 (del 6 Aprile 2005). Primo Ese Si identifichino gli errori che il compilatore segnalerebbe per il seguente programma Tipi Legami tra dichiarazioni.
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
LIP: 11 Maggio 2007 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Esercitazione 14 Marzo Esercizio dell’altra volta Definire un tipo di dato Abbonato i cui oggetti descrivono le informazioni relative ad un abbonato.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
Liste Concatenate 28 Marzo Avviso Martedi’ 4 Aprile: Verifica di LIP Per iscriversi (obbligatorio) inviare un e- mail entro venerdi’ 31 Marzo a.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 Abbiamo visto come si definiscono insiemi di stringhe, insiemi di interi, insiemi di caratteri, etc.
1 Un esempio con iteratore: le liste ordinate di interi.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
LIP: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
LIP: 18 Aprile 2008 Interfacce. Rappresentazione Lista val next vuota Lista vuota: any true Lista non vuota: any true 154 false 24 false.
Ex.1 - Astrazioni su Dati Si abbia il tipo di dato stack di interi, IntStack, specificato sotto: public class IntStack { \\ OVERVIEW: uno Stack è una collezione.
Sommario cos’è un tipo di dato astratto astrazione tramite specifica:
Transcript della presentazione:

Astrazione di dati Dati Astratti: cosa e perchè Dati Astratti: due meccanismi differenti Dati Astratti: due meccanismi differenti Astrazione e incapsulamento di dati in Java Astrazione e incapsulamento di dati in Java Specifica in Java: costruttori, operazioni Specifica in Java: costruttori, operazioni Modificabilità: produttori, modificatori, osservatori Modificabilità: produttori, modificatori, osservatori Esempi: Intset, Poly Esempi: Intset, Poly Implementazione: stato e metodi Implementazione: stato e metodi Esempi: Record Esempi: Record

Dati Astratti: cosa e perchè Dati non presenti nel linguaggioDati non presenti nel linguaggio: –insiemi, polinomi, code, … Come introdurli e usarli nei programmiCome introdurli e usarli nei programmi? Codifica:Codifica: –S: Set ->N; P: Poly->N; Q: Queue -> N –espressività

Dati Astratti: due meccanismi differenti Tipi algebrici (Ling. Funzionali): –set(t) = EmptySet + Add(t,set(t)) –set(t) = EmptySet + {t} + Union(set(t),set(t)) Astrazione = Generalizzazione + Incapsulamento (Linguaggi procedurali) –Generalizzazione - interfaccia di uso –Incapsulamento - trasparenza implementazione

Astrazione e Incapsulamento di dati in Java Oggetti: fornisconoOggetti: forniscono –rappresentazione per valori astratti e operazioni associate Classi (e gerarchie): fornisconoClassi (e gerarchie): forniscono –specifica per definire dati astratti e –regole di visibilità e di accesso per incapsulare (trasparenza) implementazione

Specifica di dati in Java Definisce: classe: overview: proprietà generali modificabilità / non-modific. costruttori: costruttori di oggetti headers: nome, parametri e tipi, eccezioni specifica: R+E operazioni: operazioni: metodi di istanza; metodi di istanza; headers: nome, parametri e tipi, eccezioni specifica: R+M+E

Modificabilità Proprietà generale: valori con o senza stato –Valori modificabili: Hanno stato modificabileHanno stato modificabile Hanno operazioni (metodi) per la modifica dello statoModificatori: Hanno operazioni (metodi) per la modifica dello stato –Valori non modificabili: Hanno stato non modificabileHanno stato non modificabile nuovi valoriProduttori: hanno operazioni (metodi) per il calcolo di nuovi valori –Osservatori: –Metodi per estrarre proprietà o visitare componenti (modificabili o non modificabili)

Esempi: specifica di IntSet public class IntSet{ //overview: gli IntSet sono oggetti modificabili per insiemi di interi. Un IntSet è un valore {x1,…,xn} per n arbitrari, distinti interi xi. //costruttori public IntSet() //Effects: inizializza this all’insieme vuoto //metodi modificatori public void insert(int x) //modifies: this //effects: aggiunge x a this se non già presente, i.e: this_post=this+{x} public void remove(int x) //modifies: this //effects: rimuove x da this se presente, i.e: this_post=this-{x} … //metodi osservatori public int size() //effects: calcola cardinalità di this… presentazione post-condizioni

Esempi: specifica di Poly public class Poly{ //overview: I Poly sono oggetti non modificabili per polinomi a coefficienti interi. Un Poly è un // valore c o +c 1 x 1 +…+c n x n, per abitrario n e c i intero possibilmente 0. //costruttori public Poly() //Effects: inizializza this al polinomio 0, i.e: n=0 & c o =0. public Poly(int c, int n) throws NegativeExponentException //Effects: se n<0 solleva l’eccezione, altrimenti inizializza this al polinomio c n x n. //metodi produttori public Poly add(Poly q) throws NullPointerException //Effects: se q==null solleva eccezione, altrimenti calcola this+q, i.e: polinomio a coefficienti // somma coefficienti di esponenti corrispondenti public void mul(Poly q) throws NullPointerException //Effects: se q==null solleva eccezione, altrimenti calcola this*q, i.e: polinomio a coefficienti // prodotto coefficienti di esponenti con somma corrispondente… //metodi osservatori public int degree() //Effects: calcola il massimo grado del polinomio.…

Implementazione: stato e metodi Rappresentazione: 1.Stato: variabili di istanzavariabili di istanza anche statiche per proprietà comunianche statiche per proprietà comuni 2. Metodi: Operano su valori implementati con tale statoOperano su valori implementati con tale stato Operano in accordo alla specifica: R+M+EOperano in accordo alla specifica: R+M+E Realizzano algoritmi di calcolo utilizzando le 3 fasi dello sviluppo:Realizzano algoritmi di calcolo utilizzando le 3 fasi dello sviluppo: 1.Specifica 2.Implementazione: a) algoritmo, b) ausiliari 3.Completamento ausiliari: ripeti 1-3 su ausiliari

Casi Semplici: Records solo stato Tipo concreto -Record -Record = n-tuple di valori non omogenei. Ogni valore selezionabile con uno specifico selettore -Rappresentazione -Rappresentazione: -solo stato -completamente accessibile (dall’esterno) -nessuna operazione specifica //---- un package che contiene la classe Poly package PolyPackage; class coppia{ // overview: una coppia di interi (x,y) per coefficiente-esponente degli addenti di un polinomio // accessibile solo nel package della classe Poly int coeff; int exp; coppia(int c, int e){ //effects: inizializza this.coeff con c, e this.exp con e; Coeff=c; exp=e;} } Package+Default

Casi Semplici: Records Tipo astratto public class coppia{ // overview: una coppia di interi (x,y), modificabile, per interi, // accessibile ovunque con selettori L (per Left) e R (per Right) private int L; private int R; public coppia(int l, int r){ //effects: inizializza this.L con l, e this.R con r; L=l; R=r;} //---- modificatori public void setL(int n){ //modifies: this //effects: modifica this.L con n L=n;} public void setR(int n){ //modifies: this //effects: modifica this.R con n R=n;} //--- osservatori: diventano i selettori public int Left(){ //effects:calcola this.L Return L;} public int Right(){ //effects:calcola this.R Return R;} } Public + Incapsulamento (accesso allo stato solo attraverso operazioni) Incapsulamento: accesso al valore solo attraverso particolari operazioni pubbliche

Astrazione di dati - 1 Implementazione di stato e metodi Quando le strutture non sono semplici: Implementazione di IntSet Implementazione di IntSet Implementazione di Poly Implementazione di Poly – stato della rappresentazione: una scelta sui valori concreti – metodi: algoritmi per le operazioni Rappresentazione: Rappresentazione: – come si sceglie? – Necessità di una metodologia

IntSet: stato La scelta dipende dalla specifica del tipo di dato. In particolare: struttura dei valori operazioni modificabilità dei valori modificabilità dei valori algoritmi di calcolo algoritmi di calcolo Valori concreti più o meno adatti per operazioni disponibili La scelta consiste in: struttura di valori concreti con cui rappresentare…

IntSet: uso Vectors public class IntSet{ //overview: gli IntSet sono oggetti modificabili per insiemi di interi. Un IntSet è un valore {x1,…,xn} per n arbitrari, distinti interi xi. private Vector els; //costruttori public IntSet() //Effects: inizializza this all’insieme vuoto {els = new Vector();} public void insert(int x) //modifies: this //effects: aggiunge x a this se non già presente, i.e: this_post=this+{x} {Integer y = new Integer(x); if (getIndex(y) < 0) els.add(y);} public void remove(int x) //modifies: this //effects: rimuove x da this se presente, i.e: this_post=this-{x} {int n = getIndex(new Integer(x)); if (n < 0) return; els.set(n,els.get(size()-1)); els.remove(els.size()-1);} … public int size() //effects: calcola cardinalità di this {return els.size();} //***** ausiliarie ******** private int getIndex(Integer x) //effects: se x occorre in this.els alla posizione i, per 0<=i<els.size()-1 restituisci i, altrimenti -1 {for (int i=0; i<els.size(); i++) if x.equals(els.get(i)) return i; return -1;} … Class Vector //modificatori public void add(Object 0); public void set(int i, Object 0); public void remove(int i); … //osservatori public Object get(int n); public int size(); ……. Private: trasparenza implementazione Ausiliarie:astrazioni+decomposizione Ausiliarie: astrazioni+decomposizione

Poly: uso array - int[] public class Poly{ //overview: I Poly sono oggetti non modificabili per polinomi a coefficienti interi. Un Poly è un // valore c o +c 1 x 1 +…+c n x n, per arbitrario n e c i intero possibilmente 0. private int[] trms; public Poly() //Effects: inizializza this al polinomio 0, i.e: n=0 & c o =0. {trms = new int[0];} public Poly(int c, int n) throws NegativeExponentException //Effects: se n<0 solleva l’eccezione, altrimenti inizializza this al polinomio c n x n. {if (n<0) throw new NegativeExponentException(“Poly:Poly” ); if(c==0) {trms = new int[0]; return;} trms = new int[n+1]; for(int j=0; j<n; j++) trms[j]=0; trms[n] = c;} public Poly add(Poly q) throws NullPointerException //effects: se q==null solleva eccezione, altrimenti calcola this+q, i.e: polinomio a coefficienti // somma coefficienti corrispondenti {if (q == null) throw new NullPointerException(“Poly:Add” ); Poly min = min(q); Poly max = max(q); int dmin = min.degree(); int dmax = max.degree(); if (dmin == dmax) for (int j=dmax; j>=0; j--) if (coeff(j)+q.coeff(j) != 0) break; else dmax--; if (dmax == -1) return new Poly(); Poly r = new Poly (max.coeff(dmax), dmax); if (dmin > dmax) r.reset(r.coeff(dmax)+min.coeff(dmax), dmax); for (int j= 0; j<=dmin & j<dmax; j++) r.reset(coeff(j)+q.coeff(j),j); for(int j= dmin+1; j<dmax; j++) r.reset(coeff(j),j); return r;} //***** ausiliari ******* private Poly reset(int c, int i) //requires: 0<=j<=degree() //modifies: this //effects: modifica in c il coefficiente di grado j di this. {trms[j] = c;} …

Rappresentazione? 1.Stato: che relazione tra stato e valore rappresentato? che relazione tra stato e valore rappresentato? 2. Metodi: …. …. Operano in accordo alla specifica: R+M+E ? … … Necessità di una metodologia

Una metodologia per Astrazioni di dati 1.Stato Concreto della rappresentazione 2.Funzione di Astrazione AF 3.Invariante di Rappresentazione I 4.Uso di AF ed I per l’implementazione dei metodi: Preservare I Verificare AF 5.Definizione degli additional: toString, clone, equals 6.Verifica: –benevolent side effects –accessibilità della rappresentazione –adeguatezza

Astrazione di dati - 2 I punti della metodologia relazione tra valore astratto e stato concreto: AF, I relazione tra valore astratto e stato concreto: AF, I ragionare sulle astrazioni di dati: ragionare sulle astrazioni di dati: – preservare I – verificare specifica con AF – correttezza: una tabella metodi addizionali (i.e. ereditati): equals, clone, toString metodi addizionali (i.e. ereditati): equals, clone, toString proprietà proprietà – benevolent side effects – accessibilità della rappresntazione – adeguatezza

Relazione tra valore Astratto e stato Concreto: AF AF: mapping C -> A AF: mapping C -> A come uno stato concreto rappresenta un valore astratto s  C, AF(s)  A non iniettiva (in generale) AF public class IntStack{ //…modificabile…un IntStack è un valore [x1,…,xn], l'ultimo inserito è xn //ed xn è il primo accessibile.… private Vector els; // AF(s)=[x1,…,xn]: (s.els.size()==n) & (n>=0) & & (0≤i<n)xi+1==s.els.get(i).intValue() C A public class IntSet{ //overview: gli IntSet sono oggetti modificabili per insiemi di interi. Un IntSet è un valore {x1,…,xn} per n arbitrari, distinti interi xi.… private int[] els; // AF(s)={s.els[i] | 0≤i<s.els.length}

Relazione tra valore Astratto e stato Concreto: invariante I I: restrizioni su C I: restrizioni su C tutti i valori concreti rappresentano un valore astratto ? AF AF parziale su C I predicato: AF(s)  A se e solo se I(s)  s  C, AF(s)  A se e solo se I(s) s.els={“ab”} s.els={“ab”} Questo vettore non può essere stato concreto di un valore per IntStack public class IntStack{ //…modificabile…un IntStack è un valore [x1,…,xn], l'ultimo inserito è xn //ed xn è il primo accessibile.… private Vector els; // AF(s) = [x1,…,xn]: (s.els.size() == n) & (n >= 0) & & (0≤i<n)xi == s.els.get(i).intValue() & (0≤i<n)xi == s.els.get(i).intValue() // I(s) = (s.els ≠ null) & (0≤i<n) s.els.get(i) instanceof Integer

Usiamo AF ed I per implementare public class IntSet{ //overview: gli IntSet sono oggetti modificabili per insiemi di interi. //Un IntSet è un valore {x1,…,xn} per n arbitrari, distinti interi xi.… private Vector els; // AF(s)={((Integer)s.els.get(i)).intValue() | 0≤i<s.els.size()} // I(s)=(s.els!=null)&(0≤i<j<s.els.size()) !((Integer)s.els.get(i)).equals(((Integer)s.els.get(j))) public IntSet() //Effects: inizializza this all’insieme vuoto {els = new Vector();} public void insert(int x) //modifies: this //effects: aggiunge x a this se non già presente, i.e: this_post=this+{x} {Integer y = new Integer(x); if (getIndex(y) < 0) els.add(y);} Perché AF ci dice che l’insieme vuoto è els con els.size()=0 els.add(y): Perché AF ci dice che se y è in els allora è in AF(this). getIndex(y): Perché I ci dice che se y è già in els allora non deve essere aggiunto

Relazione tra valore Astratto e stato Concreto: Implementiamo AF AF: mapping C -> A AF: mapping C -> A fornisce una rappresentazione esterna (output) fornisce una rappresentazione esterna (output) implementa toString ---- in Java è un additional implementa toString ---- in Java è un additional public class IntStack{ … private Vector els; // AF(s) = [x1,…,xn]: (s.els.size() == n) & (n >= 0) & (0≤i<n)xi == ((Integer)s.els.get(i)).intValue()… public String toString(){ //Effects: overidden dell’additional toString per IntStack String R = “[“; String R = “[“; for(i=0;i<els.size();i++) {R=R+((Integer)els.get(i)).intValue(); if (i<els.size()-1) R=R+”,”;}; for(i=0;i<els.size();i++) {R=R+((Integer)els.get(i)).intValue(); if (i<els.size()-1) R=R+”,”;}; return R+”]”;} return R+”]”;}

implementiamo I I: invariante su C I: invariante su C fornisce un predicato su i “termini legali” per C fornisce un predicato su i “termini legali” per C implementa repOk implementa repOk public class IntStack{ … private Vector els; // I(s) = (s.els ≠ null) & (0≤i<n)(s.els.get(i) instanceof Integer) … public boolean repOk(){ //Effects: calcola true se e solo se I(this) if (els = null) return false; for (i=0;i<els.size();i++) {if !(s.els.get(i) instanceof Integer) return false;}; return true;}

Ragionare sulle astrazioni di dati: preservare I Implementazione deve soddisfare data type induction: 1.costruttore c(T1 v1,…,Tn vn) n-ario della classe A: I(this) per ogni n-tupla di parametriI(this) per ogni n-tupla di parametri assunto I(v1)&…&I(vn) 2. produttore p(T1 v1,…,Tn vn) della classe A: I(p(v1,…,vn)) per ogni n-tupla di parametriI(p(v1,…,vn)) per ogni n-tupla di parametri assunto I(v1)&…&I(vn)&I(this) 3.modificatore m(T1 v1,…,Tn vn) n-ario della classe A: I(this_post) per ogni n-tupla di parametriI(this_post) per ogni n-tupla di parametri assunto I(v1)&…&I(vn)&I(this)

Preservare I: Esempio public class IntStack{ //…modificabile…un IntStack è un valore [x1,…,xn], l'ultimo inserito è xn … private Vector els; // I(s) = (s.els ≠ null) & (0≤i<n=s.els.size()) s.els.get(i) instanceof Integer public IntStack() //Effects: costruisce uno stack vuoto {els = new Vector();} … public void push(int i) //modifies: this //effects: inserisce i nella pila. {els.add(new Integer(i));} els diventa new Vector, quindi: this.els!=null & els.size()==0 1) I(this) per assunzione. Quindi: this.els!=null & this.els.get(i) instanceof Integer per tutti gli 0≤i< this.els.size() 2) Il corpo è els.add(new Integer(i)) quindi: this_post.els differisce da this.els per new Integer(i), all’indice this_post.els.size, che è istanza di Integer rende this_post.els certamente non null.

Ragionare sulle astrazioni di dati: verificare AF implementazione deve soddisfare specifiche: 1.costruttore c(v1…vn) n-ario della classe A: AF(this_post)  c.EAF(this_post)  c.E assunto c.R(v1)&…&c.R(vn) 2. produttore p(v1…vn) della classe A: AF(p(v1,…,vn))  p.EAF(p(v1,…,vn))  p.E assunto p.R(v1)&…&p.R(vn) 3.modificatore m(v1…vn) n-ario della classe A: AF(this_post)  m.EAF(this_post)  m.E assunto m.R(v1)&…&m.R(vn) assunto m.R(v1)&…&m.R(vn) R = requires E = effects M = modifies

Verificare AF: esempio public class IntStack{ //…modificabile…un IntStack è un valore [x1,…,xn], l'ultimo inserito è xn … private Vector els; // AF(s) = [x1,…,xn]: (s.els.size == n) & (n >= 0) & (0≤i<n)xi == s.els.get(i).intValue() public IntStack() //Effects: costruisce uno stack vuoto {els = new Vector();} … public void push(int i) //modifies: this //effects: inserisce i nella pila. {els.add(new Integer(i));} els diventa new Vector, quindi: this.els!=null & els.size()==0 ==> AF(this)=[] els.add(v) ==> this_post.els.get(j)=this.els.get(j)  0≤j<this_post.els.size()-1 ==> AF(this_post)=[x1,…,xn,v] se AF(this)=[x1,…,xn]

Correttezza: una tabella Classe A Public class A{…} //O: …invariante sugli oggetti… Rep //AF(c)= … //I(c)= … //costruttoriA(param)//R,E:…{B} R(param), B => E(AF(this)) B => I(this) //modificatori Public void M(param)//R,M,E…{B} R(this,param), B => E(AF(this_post)) I(this ), B => I(this_post) //produttori Public A P(param)//R,E…{B} R(this,param), B => E(AF(P(param))) I(this), B => I(P(param)) //osservatori Public Type V(param)//R,E…{B} R(this,param), B => E(AF(V(param))) //privati private Type T(param)//R,M,E…{B} private Type T(param)//R,M,E…{B} come modificatori se mod. = produttori se prod. = produttori se prod. = osservatori se oss. = osservatori se oss. Costrutti Specifica/Verifica

Metodi addizionali (i.e. ereditati): equals, clone, toString Equals = uguaglianza ridefinibile su oggetti == esiste sui primitivi. Sugli oggetti opera by-reference == esiste sui primitivi. Sugli oggetti opera by-reference behaviorally equivalent (indistinguibili w.r.t. applicazione dei metodi) behaviorally equivalent (indistinguibili w.r.t. applicazione dei metodi) definita sulla classe Object per i mutable definita sulla classe Object per i mutable modificabili: operare by reference modificabili: operare by reference non-modificabili: operare per equivalenza di stato non-modificabili: operare per equivalenza di stato Contenuti in Object Contenuti in Object Ereditati (come sono) o Overidden (ridefiniti) Ereditati (come sono) o Overidden (ridefiniti)

Esempio: Equals public class Main { //overview: contiene un main per il testing di equals // su string. public static void main(String[] a){ String s = "abc"; String r = "abc"; System.out.print("s == r calcola: "); System.out.println(r==s); System.out.println("s.equals(r) calcola: " + s.equals(r)); }} … false … true public class Main2 { //overview: contiene un main per il testing di equals su // oggetti modificabili. public static void main(String[] a) throws NullIntStackException{ IntStack S = new IntStack(); S.push(3);S.push(4); IntStack R = new IntStack(); R.push(3);R.push(4); IntStack T = R; System.out.print("R == S calcola: "); System.out.println(R == S); System.out.println("R.equals(S) calcola: " + R.equals(S)); System.out.println("R.equals(T) calcola: " + R.equals(T)); }} … false … true … private int top; private ImmutableIntStack pop; … public boolean equals(Object S) //effects: calcola true se e solo se this e S hanno stesso stato, // i.e.: sono equals i componenti. {ImmutableIntStack V = (ImmutableIntStack)S; if (pop == null) return(V !=null && ((top ==V.top) & if (pop == null) return(V !=null && ((top ==V.top) & (V.pop == null)); (V.pop == null)); if (V.pop == null) return false; if (V.pop == null) return false; return ((top == V.top) & (pop.equals(V.pop)));} return ((top == V.top) & (pop.equals(V.pop)));} public class Main3 { //overview: contiene un main per il testing di equals // su oggetti non-modificabili. public static void main(String[] a) throws NullIntStackException{ ImmutableIntStack S = new ImmutableIntStack(3); ImmutableIntStack R = new ImmutableIntStack(3); System.out.println("R.equals(S) calcola: " + R.equals(S)); System.out.println("R == S calcola: " + R == S); }} … true … false

Clone: mutable e immutable Clone = copia di oggetto definita sulla classe object per gli immutable definita sulla classe object per gli immutable modificabili: copiare lo stato con copia dei componenti modificabili: copiare lo stato con copia dei componenti non-modificabili: copiare lo stato non-modificabili: copiare lo stato public class IntStack{ //.. modificabile.. … private Vector els; … //additional: overriding di clone public Object clone() //effects: crea una copia "completa" ed indipendente // di this. {IntStack C = new IntStack(); for (int i=0;i<els.size();i++) C.els.add(i,els.get(i)); for (int i=0;i<els.size();i++) C.els.add(i,els.get(i)); return C; return C; } public class IntSet{ //.. Non modificabile.. … private Vector els; … //additional: overriding di clone --- inutile public Object clone() //effects: crea una copia dello stato {IntSet C = new IntSet(); C.els = els; C.els = els; return C; return C; }

Proprietà: benevolent s.e. Quando AF non è iniettiva allora possiamo avere: Side effects non previsti dalla specifica di un metodo Side effects non previsti dalla specifica di un metodo Che mantengono I Che mantengono I Soddisfano specifica del metodo Soddisfano specifica del metodo Vantaggiosi in alcuni casi: ad esempio: un metodo osservatore max (isIn) su IntSet che calcola il massimo degli interi contenuti e modifica ad esempio: un metodo osservatore max (isIn) su IntSet che calcola il massimo degli interi contenuti e modifica la rappresentazione interna (disposizione degli interi la rappresentazione interna (disposizione degli interi nel vettore) per utilizzare un’algoritmo di ricerca che nel vettore) per utilizzare un’algoritmo di ricerca che prevede di cambiare la disposizione degli elementi via prevede di cambiare la disposizione degli elementi via via che sono visitati. via che sono visitati.

Proprietà: + accesso della rappresentazione + adeguatezza Rappresentazione garantita da: 1)variabili componenti stato dichiarate private 2)Metodi pubblici non hanno parametri che espongono componenti della rappresentazione 3) Metodi pubblici non calcolano valori che espongono componenti della rappresentazione