Ese 3 (del 3 Aprile 2003)
Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi siano di tipo Object e che le operazioni primitive in aggiunta al costruttore siano: push, pop, top e isempty Definire una procedura stand-alone che, dato uno Stack contenente interi, lo modifichi, rimpiazzando gli ultimi due elementi inseriti con la loro somma.
Specifica public class Stack { \\ OVERVIEW: uno Stack e’ una collezione di oggetti (Object) organizzati per ordine di inserimento con una politica LIFO. E’ modificabile public Stack () { \\ EFFECTS: costruisce uno Stack Vuoto } public boolean isEmpty() { \\ EFFECTS: se this e’ vuoto restituisce true, altrimenti false } public Object top() throws EmptyException { \\ EFFECTS: se this e’ vuoto solleva EmptyException, altrimenti ritorna l’ultimo elemento inserito }
Modificatori public void pop() throws EmptyException { \\ MODIFIES: this \\ EFFECTS: se this non e’ vuoto rimuove l’ultimo elemento inserito, altrimenti \\ solleva EmptyException } public void push (Object o) throws NullPointerException { \\ MODIFIES: this \\ EFFECTS: se o e’ null solleva NullPointerException, altrimenti \\ inserisce o nella pila }
Implementazione Rappresentazione: usiamo un Vector per implementare la pila, l’ultimo elemento inserito e’ l’ultimo elemento (top della pila) Implementiamo i metodi di conseguenza
Implementazione public class Stack { \\ OVERVIEW: uno Stack e’ una collezione di oggetti (Object) organizzati per ordine di inserimento con una politica LIFO. E’ modificabile private Vector pila \\ rappresentazione privata public Stack () { \\ EFFECTS: costruisce uno Stack vuoto pila=New vector();} public boolean isEmpty() { \\ EFFECTS: se this e’ vuoto restituisce true, altrimenti false if (pila.size()==0) {return true;}; return false; }
public Object top() throws EmptyException {\\ EFFECTS: se this e’ vuoto solleva EmptyException, altrimenti ritorna l’ultimo elemento inserito if (isEmpty()) {throw new EmptyException(“Stack.top”);}; return pila.get(pila.size()-1)); } public void pop() throws EmptyException { \\ MODIFIES: this \\ EFFECTS: se this non e’ vuoto rimuove l’ultimo elemento inserito, altrimenti solleva EmptyException if (isEmpty()) {throw new EmptyException(“Stack.pop”);}; pila.remove(pila.size()-1));} public void push (Object o) throws NullPointerException { \\ MODIFIES: this \\ EFFECTS: se o e’ null solleva NullPointerException, altrimenti inserisce o nella pila if (o==null){throw new NullPointerException(“Stack.pop”);}; pila.add(o);} }
Procedura stand-alone Scritta vedendo solo la specifica di Stack (non vediamo la rappresentazione, ovvero la variabile d’istanza pila di tipo Vector) Bisogna fare attenzione che i valori ritornati da top hanno tipo apparente Object Assumiamo che lo Stack contenga Integer
public static void sum (Stack p) throws NondueValExc { int primo, secondo; try {primo =((Integer) p.top().intValue();} catch(EmptyException) {throw new NondueValExc(“sum”);} p.pop(); try {secondo =((Integer) p.top().intValue();} catch(EmptyException) {p.push(new Integer (primo)); throw new NondueValExc(“sum”);} p.pop(); p.push( new Integer (primo+secondo)); } Notate che se c’e’ solo un valore nella pila, prima di sollevare l’eccezione bisogna rimettere il valore tolto in precedenza
Commenti Se avessimo messo la rappresentazione pubblica, (ovvero il vettore pila) Implementazione piu’ efficiente, ma metodologicamente sbagliata (si rompe l’astrazione rendendo la procedura dipendente dall’implementazione di Stack) Bisogna usare i metodi pubblici forniti da Stack
Esempio public static void sum (Stack p) throws NondueValExc { if (p.pila.size()<2) {throw new NondueValExc(“sum”);} int primo, secondo; primo =((Integer) p. pila.get(p.pila.size()-1).intValue(); secondo =((Integer) p. pila.get(p.pila.size()-2).intValue(); p.pila.remove(p.pila.size()-1); p.pila.set(p.pila.size(0-1), new Integer (primo+secondo)); }