LIP: 15 Marzo 2005 Vettori di interi
Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo crescente Vediamo la descrizione di metodi e costruttori Definiscono le operazioni sugli oggetti di tipo VectorInt
public VectorInt(){ \\EFFECTS\\EFFECTS: crea un vettore di interi vuoto} public int size (){ \\EFFECTS\\EFFECTS: restituisce il numero di elementi presenti nel vettore} public int get (int index){ \\EFFECTS\\EFFECTS: restituisce l'elemento di indice index } public void add (int n){ \\MODIFIES:this \\EFFECTS\\EFFECTS: aggiunge il valore n nel vettore} public void remove(int index){ \\MODIFIES:this \\EFFECTS: rimuove l'oggetto presente nella posizione index e sposta all'indietro di una posizione tutti gli elementi successivi a quello rimosso} public void set (int n, int index){ \\MODIFIES:this \\EFFECTS\\EFFECTS: modifica this sostituendo il valore n in posizione index } public String toString(){ \\EFFECTS\\EFFECTS: restituisce una stringa che contiene tutti gli elementi presenti nel vettore this }
Sull’implementazione Usare per memorizzare il vettore di interi una variabile d’istanza privata private Vector elements; Tutti i metodi (a parte il metodo overridden toString()) si realizzano facilmente chiamando i metodi corrispondenti della classe Vector (devono essere importati da java.util.Vector) Implicitamente stiamo assumendo che se c’e’ un accesso ad un indice non presente nell’vettore venga sollevata un’eccezione come nella chiamata dei metodi corrispondenti di Vector (andrebbe in realta’ inserito esplicitamente nei commenti informali)
Commenti Attenzione solo ai tipi (i metodi della classe vogliono e restituiscono int) Gli elementi di Vectorint sono omogenei (sono tutti interi) Bisogna mantenere l’ordinamento (tipo nel metodo add) Come facciamo a memorizzare interi nel Vector? elements.addElement(3); errore di tipo! Bisogna convertire il tipo primitivo nel corrispondente tipo involucro e vice- versa elements.addElement(new Integer(3));
Testing E’ buona pratica sviluppare in parallelo un main che serve per testare VectorInt Creare un VectorInt vuoto, aggiungere, rimuovere, modificare (e verificarne via via il contenuto) Attenzione (il vettore interno non e’ visibile, e’ privato) bisogna accedere tramite l’interfaccia pubblica (metodi e costruttori di VectorInt ) Usare il metodo toString() (conviene quindi definirlo da subito) per leggere lo stato interno
Definire poi una classe VectorIntOp che contiene metodi statici (procedure stand-alone) che operano su VectorInt In particolare,
Metodi statici public static int max(VectorInt v){ \\EFFECTS\\EFFECTS: restituisce il valore massimo contenuto in v, se e’ vuoto zero} public static boolean search(VectorInt v,int i){ \\EFFECTS\\EFFECTS: restituisce true se il valore i occorre nel vettore, false altrimenti}
Implementazione Attenzione (il vettore interno non e’ visibile, e’ privato) Per realizzare i metodi statici bisogna usare l’interfaccia pubblica (metodi della classe VectorInt) Come vedremo nascondere le variabili d’istanza (ovvero il modo in cui e’ implementato lo stato interno degli oggetti e’ fondamentale) Intuitivamente questo permette di rendere il codice che usa il tipo di dato VectorInt (p.e. le procedure statiche) indipendente dalla sua implementazione Posso cambiare l’implementazione senza dovere riimplementare tutti i moduli che lo usano
Implementazione Nell’implementazione dei metodi statici E’ necessario sfruttare l’ordinamento Piu’ efficiente
Estenderlo per i nuovi metodi statici Il testing non puo’ chiaramente garantire che tutto funzioni correttamente E’ fondamentale scegliere dei casi significativi che rappresentino le situazioni interessanti Per esempio per testare un metodo di ricerca provare un valore che c’e’ e uno che non c’e’ Ricordarsi di testare anche il caso del vettore vuoto Testing
Tester