Esercitazione 14 Marzo 2006 Esercizio dellaltra volta Definire

  • Slides: 25
Download presentation
Esercitazione 14 Marzo 2006

Esercitazione 14 Marzo 2006

Esercizio dell’altra volta • Definire un tipo di dato Abbonato i cui oggetti descrivono

Esercizio dell’altra volta • Definire un tipo di dato Abbonato i cui oggetti descrivono le informazioni relative ad un abbonato al telefono: nome (di tipo String ) e numero di telefono (int) • Definire un tipo di dato Elenco i cui oggetti descrivono collezioni (ordinate) di abbonati

Modo giusto di procedere • Scegliere le variabili d’istanza che sono in grado di

Modo giusto di procedere • Scegliere le variabili d’istanza che sono in grado di memorizzare le informazioni richieste • Metterle private • Implementare i metodi di conseguenza

Rappresentazione Privata • Garantisce che il codice che usa - Elenco -Abbonato lo faccia

Rappresentazione Privata • Garantisce che il codice che usa - Elenco -Abbonato lo faccia tramite la loro interfaccia pubblica (metodi e costruttori della classe)

public class Abbonato{ private String nome; private int num; public Abbonato(String s, int n){

public class Abbonato{ private String nome; private int num; public Abbonato(String s, int n){ \EFFECTS: crea un nuovo abbonato con nome s \ e numero n nome=n; num=m; } public String nome(){ \EFFECTS: restituisce il nome di this return nome; } public int numero(){ \EFFECTS: restituisce il numero di this return num; }

\ metodo overridden public boolean equals(Object o){ \REQUIRES: o e’ di tipo Abbonato \EFFECTS:

\ metodo overridden public boolean equals(Object o){ \REQUIRES: o e’ di tipo Abbonato \EFFECTS: restituisce true se this ed o sono uguali String x= ((Abbonato) o). nome; int y=((Abbonato) o). num; if (this. nome. equals(x) && this. num==y) {return true; } else {return false; } } } NOTA: cast necessario perche’ il tipo apparente del parametro e’ Object ALTERNATIVA (OVERLOADING): public boolean equals(Abbonato o)

 • Elenco e’ una collezione di elementi di tipo Abbonato • Gli Abbonati

• Elenco e’ una collezione di elementi di tipo Abbonato • Gli Abbonati sono mantenuti all’interno dell’Elenco in modo ordinato rispetto al nome, ESEMPIO: (Francesca, 2867) <= (Marco, 133) • Inoltre i numeri di telefono nell’elenco sono tutti diversi • Va implementata usando l’interfaccia pubblica di Abbonato private String nome; private int num; ACCESSO PROIBITO

Per semplicita’ • Facciamo vedere una versione non ordinata • Implementiamo l’elenco usando una

Per semplicita’ • Facciamo vedere una versione non ordinata • Implementiamo l’elenco usando una variabile di tipo Vector • L’elenco e’ modificabile

public class Elenco{ //OVERVIEW: un Elenco e' una collezione (non ordinata) di Abbonati, //

public class Elenco{ //OVERVIEW: un Elenco e' una collezione (non ordinata) di Abbonati, // ognuno con un numero di telefono diverso private Vector persone; // memorizza l’elenco private static int proxnumero=1; // permette di generare nuovi numeri tel. public Elenco(){ \EFFECTS: crea un nuovo elenco vuoto persone=new Vector(); }

public int cercanum(String s) { \EFFECTS: restituisce il numero di telefono del primo abbonato

public int cercanum(String s) { \EFFECTS: restituisce il numero di telefono del primo abbonato presente in this che ha nome s, altrimenti restituisce 0 for (int j=0; j< persone. size(); j++){ Abbonato a= (Abbonato) persone. element. At(j); if (s. equals(a. nome()) ) {return a. numero(); } } return 0; } • cast necessari quando si leggono gli elementi del Vector • per accedere alle informazioni dell’abbonato a bisogna usare l’interfaccia pubblica

public void inserisci(String s){ \MODIFIES: this \EFFECTS: aggiunge un nuovo Abbonato all’elenco (this) con

public void inserisci(String s){ \MODIFIES: this \EFFECTS: aggiunge un nuovo Abbonato all’elenco (this) con nome s e con un nuovo numero di telefono Abbonato a=new Abbonato(s, proxnumero); proxnumero=proxnumero+1; persone. add. Element(a); //inserimento non ordinato } public void rimuovi(String s){ \MODIFIES: this \EFFECTS: rimuove dall’elenco (this) tutti gli abbonati con nome s for (int j=0; j< persone. size(); j++){ Abbonato a= (Abbonato) persone. element. At(j); if (s. equals(a. nome()) ) persone. remove. Element. At(j); //versione non ordinata } }

public int cambia(String s, int x){ \MODIFIES: this \EFFECTS: se nell’elenco compare l’abbonato (s,

public int cambia(String s, int x){ \MODIFIES: this \EFFECTS: se nell’elenco compare l’abbonato (s, x), rimpiazza il numero x con un nuovo numero di telefono y e lo restituisce for (int j=0; j< persone. size(); j++){ Abbonato a= (Abbonato) persone. element. At(j); if (s. equals(a. nome()) && x== a. numero()) {Abbonato nuovo=new Abbonato(s, proxnumero); persone. set. Element. At(nuovo, j); // uso dell'interfaccia pubblica proxnumero=proxnumero+1; return nuovo. numero(); }} return 0; } public String to. String(){ \EFFECTS: standard String s="["; for (int j=0; j< persone. size(); j++){ Abbonato a= (Abbonato) persone. element. At(j); s= s + "(" + a. nome() + ", " + a. numero() + ")"; } return s + "]"; }

Interfaccia Pubblica • Elenco usa il tipo di dato Abbonato • Sarebbe piu’ facile

Interfaccia Pubblica • Elenco usa il tipo di dato Abbonato • Sarebbe piu’ facile scrivere il codice di Elenco, accedendo alla rappresentazione di Abbonato

Esempio: metodo cambia Versione che usa solo l’interfaccia pubblica: Abbonato a= (Abbonato) persone. element.

Esempio: metodo cambia Versione che usa solo l’interfaccia pubblica: Abbonato a= (Abbonato) persone. element. At(j); if (s. equals(a. nome()) && x== a. numero()) {Abbonato nuovo=new Abbonato(s, proxnumero); persone. set. Element. At(nuovo, j); } Versione che accede alle variabili: Abbonato a= (Abbonato) persone. element. At(j); if (s. equals(a. nome) && x== a. num) {a. num=proxnumero; }

Interfaccia Pubblica • Questo approccio e’ metodologicamente sbagliato • Mantenere l’implementazione nascosta permette di

Interfaccia Pubblica • Questo approccio e’ metodologicamente sbagliato • Mantenere l’implementazione nascosta permette di -garantire proprieta’ del tipo di dato -rendere il codice che lo usa indipendente dalla sua implementazione

Esempio • Se cambiassimo l’implementazione di Abbonato • L’implementazione di Elenco scritta in base

Esempio • Se cambiassimo l’implementazione di Abbonato • L’implementazione di Elenco scritta in base all’interfaccia pubblica continua a funzionare • Le due implementazioni sono indipendenti • Nell’altro modo ogni modifica del tipo di dato Abbonato richiederebbe di riprogettare anche Elenco

Esercizio Proposto • Abbiamo visto: pila (Stack) di interi • Mantiene gli elementi per

Esercizio Proposto • Abbiamo visto: pila (Stack) di interi • Mantiene gli elementi per ordine di inserimento (LIFO) Struttura dati analoga: coda (queue) • Mantiene gli elementi per ordine di inserimento (FIFO)

Esempio Coda di elementi di tipo Intero: [8, 5, 9] - 9 e’ il

Esempio Coda di elementi di tipo Intero: [8, 5, 9] - 9 e’ il primo elemento della coda (il primo arrivato) Se inseriamo l’elemento 3: [3, 8, 5, 9] Se rimuoviamo il primo elemento: [3, 8, 5]

Per esempio: coda di interi • is. Empty() serve per testare se la coda

Per esempio: coda di interi • is. Empty() serve per testare se la coda e’ vuota • first() serve per leggere il primo elemento della coda, quello inserito per primo • remove() rimuove il primo elemento della coda • insert (int x) inserisce x nella coda come ultio elemento

Specifica (INTERFACCIA PUBBLICA) public class Coda { \ OVERVIEW: una coda e’ una collezione

Specifica (INTERFACCIA PUBBLICA) public class Coda { \ OVERVIEW: una coda e’ una collezione di interi organizzati per ordine di inserimento con una politica FIFO. E’ modificabile public Coda () { \ EFFECTS: costruisce una Coda Vuota } public boolean is. Empty() { \ EFFECTS: se this e’ vuoto restituisce true, altrimenti false } public int first() { \ REQUIRES: this non e’ vuoto \ EFFECTS: restituisce il primo elemento di this }

public void remove() { \ REQUIRES: this non e’ vuoto \ MODIFIES: this \

public void remove() { \ REQUIRES: this non e’ vuoto \ MODIFIES: this \ EFFECTS: se this non e’ vuoto rimuove il primo elemento} public void insert (int x) { \ MODIFIES: this \ EFFECTS: inserisce x nella coda (come ultimo elemento) } public void insertall (int[] a) { \ MODIFIES: this \ EFFECTS: inserisce gli elementi di a nella coda (dal primo all’ultimo) }

public boolean equals(Object o) { \ REQUIRES: o e’ di tipo Coda \ EFFECTS:

public boolean equals(Object o) { \ REQUIRES: o e’ di tipo Coda \ EFFECTS: restituisce true sse this ed o hanno gli stessi elementi} public String to. String () { \ EFFECTS: restituisce una stringa che descrive il contenuto di this, ovvero \ la sequenza degli elementi } }

Implementazione • Simile a quella di Stack • E’ meglio usare una variabile di

Implementazione • Simile a quella di Stack • E’ meglio usare una variabile di tipo Vector per mantenere gli elementi private Vector coda; \rappresentazione privata

Rappresentazione Privata • Non fa differenza dal punto di vista del codice che implementa

Rappresentazione Privata • Non fa differenza dal punto di vista del codice che implementa Coda • Ma solo dal punto di vista di chi usa il tipo di dato coda • Dovete progettare anche una classe di procedure statiche usano Coda

Specifica public class Proc { public static Coda add(Coda a, int x) { REQUIRES:

Specifica public class Proc { public static Coda add(Coda a, int x) { REQUIRES: a e’ diverso da null EFFECTS : restituisce una coda che e’ ottenuta da a, aumentando ogni elemento di x. Esempio: a=[4, 3, 9, 1] e x=2 allora restituisce =[6, 5, 11, 3] } public static int sum(Coda a) { REQUIRES: a e’ diverso da null EFFECTS : restituisce la somma degli elementi di a} public static Coda reverse(Coda a) { REQUIRES: a e’ diverso da null EFFECTS : restituisce una coda che e’ l’inverso di a Esempio: a=[4, 3, 9, 1] allora restituisce =[1, 9, 3, 4] }