Esercitazione Object, Vettori, Liste. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo lo.

Slides:



Advertisements
Presentazioni simili
Tipi di dato astratti Lista, Pila, Coda, Albero.
Advertisements

Differenze nei vari linguaggi di Elisa Trifirò e Barbara Tacchino
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
1 Semantica Operazionale di un frammento di Java: lo stato.
Classi ed Oggetti in Java (Cenni). Richiami Ruolo delle Classi in Java Oggetti.
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.
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.
Specifiche senza JML: uso delle asserzioni. 2 Asserzioni in Java Dal jdk 1.4 (da Febbraio 2002) cè meccanismo per gestire asserzioni Asserzione: espressione.
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.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Fopndamenti di programmazione. 2 La classe String Una stringa è una sequenza di caratteri La classe String è utilizzata per memorizzare caratteri La classe.
Astrazione procedurale ed eccezioni
1 Un esempio con iteratore: le liste ordinate di interi.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
1 Eccezioni in Java. 2 Ricordiamo che 4 una procedura può terminare –normalmente, ritornando un risultato –in modo eccezionale ci possono essere diverse.
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.
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.
Compitino del 2004 Alberi Generici. Idea Si vuole un tipo di dato astratto che definisca una struttura ad albero in cui nodi e foglie hanno associato.
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)
LIP: 9 Maggio Esercizi Riprendiamo un esercizio proposto Definire un tipo di dato Persona che definisce oggetti che rappresentano le informazioni.
1 Progettare un Tipo di Dato Astratto. 2 Scelte di Progetto (astrazione) 4 Caratteristiche degli oggetti –Modificabilità 4 Scelta delle operazioni –Realizzare.
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.
Programmazione in Java. Classi I programmi in Java consistono di classi. Le classi consentono di definire: collezioni di procedure (metodi statici) tipi.
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 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
LIP: 8 Marzo 2005 Vettori. Abbiamo visto L’uso di Vector come alternativa all’uso di arrays Rivediamo l’esercizio dell’altra volta.
Esercitazione del 7 marzo 2008 Ereditarieta’. Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro.
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.
LIP: 22 Marzo 2005 Eccezioni. Eccezioni-Richiami Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
Esercizio 3. Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare i commenti.
Cose nuove di Java (prima a chiacchiera, poi formalmente)
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
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.
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
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.
1 Laboratorio di Introduzione alla Programmazione §II MODULO §3 crediti §Esame e voto unico (su 6 crediti totali)
Ereditarieta’. Contenuti Introduciamo un meccanismo fondamentale di Java: l’ereditarieta’ Permette di estendere classi gia’ definite (ovvero di definire.
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.
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.
Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo.
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.
Introduzione a Java. Java Linguaggio Object-Oriented La maggior parte dei dati manipolati dai programmi e’ contenuta in oggetti La principale forma di.
Liste Concatenate 28 Marzo Avviso Martedi’ 4 Aprile: Verifica di LIP Per iscriversi (obbligatorio) inviare un e- mail entro venerdi’ 31 Marzo a.
Esercitazione sull’ ordinamento 20 maggio 2003
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.
Corso di Algoritmi e Strutture Dati con Laboratorio Richiami di Java – parte II.
Transcript della presentazione:

Esercitazione Object, Vettori, Liste

Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo lo stato degli oggetti -aggiungendo nuove operazioni Se c1 estende c2, c1 e’ un sottotipo di c2

Ricordiamo che Se una classe c1 estende la classe c2 -c1 eredita tutte le variabili ed i metodi d’istanza di c2 (a meno di overriding) -puo’ accedere a tutte le variabili e ai metodi statici di c2

Classe Object La classe Object è la superclasse, diretta o indiretta, di ciascuna classe in Java Object è supertipo di qualsiasi oggetto

Attenzione I tipi primitivi int, boolean, double non sono sottotipi di Object, non sono oggetti (vedi la differenza nella semantica) String e’ un tipo primitivo sottotipo di Object BankAccount, Persona sono esempi di tipi non primitivi sottotipi di Object

A cosa serve? Grazie al meccanismo dell'ereditarietà  i suoi metodi sono ereditati da tutti i sottotipi  ad una variabile di tipo Object possiamo assegnare oggetti di qualsiasi tipo (principio di sostituzione) Un oggetto del supertipo puo’ essere usato ovunque sia richiesto un valore del supertipo

Esempio Object obj; String s=“io”; Obj=s; \\ e’ corretto un sottotipo e’ assegnato ad un supertipo BankAccount b=new BankAccount(); Obj=b; \\ e’ corretto un sottotipo e’ assegnato ad un supertipo Obj=4; \\ e’ un errore non e’ sottotipo Analogamente un metodo che ha un parametro formale Object potrebbe essere chiamato con un parametro attuale del sottotipo Meccanismo essenziale per utilizzare lo stesso codice per i vari sottotipi

Sono metodi ereditati da tutti i sottotipi (devono tipicamente essere sovrascritti) I metodi più utili sono: public String toString() { \\EFFECTS: restituisce una rappresentazione\\EFFECTS dell'oggetto this in forma di stringa. } public boolean equals(Object obj) \\EFFECTS :verifica se l'oggetto this è uguale a obj.\\EFFECTS Metodi Eredidati da Object

Commenti a toString() La definizione del metodo nella classe Object restituisce una stringa che contiene il nome della classe dell'oggetto ed una rappresentazione esadecimale del codice hash dell'oggetto (indirizzo in memoria dell'oggetto). Questo accade perché la classe Object non può conoscere la struttura dell'oggetto. Il metodo ereditato e’ poco utile. Il metodo deve quindi essere sovrascritto in ogni classe che lo usa per ottenere un risultato significativo. Tipicamente, di un oggetto si vogliono mostrare (nella stringa restituita) i valori delle variabili d'istanza o comunque una informazione significativa che descriva lo stato interno

Commenti ad Concettualmente, l'invocazione.equals( ) del metodo equals dovrebbe restituire true quando il contenuto dei due oggetti è uguale (non il riferimento, come per l'operatore ==). L'esempio tipico è il confronto tra stringhe. D’altra parte il metodo equals della classe Object, e’ implementato non potendo fare alcuna assunzione sulla struttura interna degli oggetti su cui viene invocato (utilizza semplicemente l'operatore == per confrontarli.) Deve quindi essere sovrascritto in modo opportuno nel sottotipo (overriding) a seconda delle caretteristiche degli oggetti Per il tipo String il metodo e’ gia’ ridefinito in modo primitivo equals

Object come supertipo Utilizzando Object e’ possibile definire collezioni di dati generiche Non hanno un tipo fissato, ma sono in grado di memorizzare elementi di ogni sottotipo di Object Vediamone un esempio tramite un tipo di dato primitivo, vettori Analizzeremo la classe Vector Simile all’array, i vettori permettono di memorizzare sequenze di valori di dimensione variabile Esistono anche altri tipi di dato primitivo, simili. Consideriamo un caso come esempio

Un tipo di dato primitivo La classe java.util.Vector permette di definire degli oggetti chiamati vettori ( Vector ) -memorizzano sequenze di oggetti di lunghezza variabile -possono memorizzare oggetti di tipo diverso, purche’ sottotipi di Object, (es. String, etc.)

Tipo Simili agli array a parte il fatto che la dimensione di un vettore può variare durante l'esecuzione di un programma non vanno creati per un tipo prefissato, le posizioni del Vector hanno un tipo generico Object quindi possono contenere oggetti di ogni tipo anche tra loro disomogenei (tipo String o Integer) grazie al principio di sostituzione Vector

Tipo Vediamo la specifica Principali costruttori e metodi Non daremo una trattazione completa Vector

Costruttore public Vector (){ \\EFFECTS\\EFFECTS: crea un vettore vuoto} Notate che a differenza che per gli arrays non e’ necessario fissare al momento della creazione la dimensione

public int size (){ \\EFFECTS\\EFFECTS: restituisce il numero di elementi presenti nel vettore} public Object elementAt (int index){ \\EFFECTS\\EFFECTS: restituisce l'elemento di indice index } public void setElementAt (Object obj, int index){ \\MODIFIES\\MODIFIES: this \\EFFECTS\\EFFECTS: sostituisce obj all'oggetto della posizione index} Se l’index non e’ presente nel vettore viene sollevata una eccezione come per gli arrays Metodi simili a quelli dell’array

public void insertElementAt (Object obj, int index){ \\MODIFIES:this \\EFFECTS: inserisce obj nella posizione index e sposta tutti gli\\EFFECTS elementi, da index in poi, di una posizione} public void addElement (Object obj){ \\MODIFIES:this \\EFFECTS\\EFFECTS: aggiunge una posizione alla fine che contiene obj } La dimensione del Vector cambia, viene aggiunta una posizione alla fine o in un dato punto Metodi per aggiungere

public void removeElementAt (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 boolean removeElement (Object obj){ \\MODIFIES:this \\EFFECTS: rimuove la prima occorrenza dell'oggetto obj se presente restituendo true,oppure restituisce false} La dimensione del Vector cambia, viene ricompattato (non rimane una posizione vuota) Metodi per rimuovere

Vector per memorizzare stringhe Vector v=new Vector(); \\ [] inizialmente vuoto v.addElement(“a”); \\ [a] v.addElement(“b”); \\ [a,b] v.addElement(“c”); \\ [a,b,c] v.removeElementAt(1); \\ [a,c]

Come leggere gli elementi? public Object elementAt (int index){ \\EFFECTS\\EFFECTS: restituisce l'elemento di indice index } Vector v=new Vector(); \\ [] v.addElement(“a”); \\ [a] v.addElement(“b”); \\ [a,b] v.addElement(“c”); \\ [a,b,c] String s= v.elementAt(0); \\ e’ corretto? Sembrerebbe, dovrebbe restituire una stringa, ma……..

Problema:errore di compilazione Stiamo usando un tipo Vector per memorizzare stringhe, ma il Vector e’ dichiarato generico Vector v=new Vector(); \\ non si fissa il tipo degli elementi String[] v=new String[5]; \\ differenza con l’array il compilatore non puo’ sapere quale tipo di valori sono correntemente memorizzati nella prima posizione del Vector (il suo tipo effettivo) il compilatore conosce solo il tipo restituito dal metodo (il suo tipo apparente)

Necessario: Cast Vector v=new Vector(); \\ [] v.addElement(“a”); \\ [a] v.addElement(“b”); \\ [a,b] v.addElement(“c”); \\ [a,b,c] String s= ((String) v.elementAt(0)); \\ compila Il compilatore non riporta errori in quanto String e’ sottotipo del tipo apparente Object Il Cast potrebbe provocare un errore a run-time qualora il valore restituito dal metodo non fosse sottotipo di String

Tipi Primitivi? Vector elements=new Vector(); elements.addElement(3); errore di tipo! int non e’ sottotipo di Object (il metodo addElement ha parametro Object) Analoghi problemi per gli altri tipi boolean, double…

La soluzione Ogni tipo primitivo ha un corrispondente sottotipo di Object, sono oggetti che memorizzano i valori corrispondenti Per esempio, Integer e’ la classe involucro di int Ogni Integer e’ un oggetto che memorizza un valore int Integer e’ sottotipo di Object Classi analoghe per tutti gli altri tipi primitivi

Integer ha (oltre ai soliti metodi toString e equals ): un costruttore con parametro di tipo primitivo public Integer(int value){ \\EFFECTS: crea un Integer che contiene il valore value}\\EFFECTS un metodo che produce il valore di tipo primitivo corrispondente public int intValue(){ \\EFFECTS: restituisce il numero intero contenuto in this}\\EFFECTS

Esempio Vogliamo memorizzare il valore 3 in un Vector Integer e= new Integer(3); //creiamo l’Integer elements.addElement(e); //lo inseriamo Vogliamo leggere un valore da un Vector di Integer e trasformarlo in int Integer i= (Integer) elements.elementAt(3); //Cast int x= i.intValue();//conversione

E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata serve per rappresentare sequenze di elementi (di dimensione variabile) [ ] [] Le operazioni permettono di aggiungere elementi all’inizio o alle fine, e di scorrere la lista Facciamo vedere una realizzazione ricorsiva in Java

Tipo di dato ricorsivo Definizione ricorsiva: una lista concatenata e’ vuota o e’ un nodo che contiene un valore e un riferimento al resto della lista

Esempio Lista non vuota: val next Primo elemento 1164 Lista vuota

IntList Vediamo per esempio una possibile specifica nel caso di elementi di tipo Integer Definiamo un tipo di dato astratto modificabile Si puo’ ovviamente anche definire non modificabile

Specifica di IntList public class IntList { // OVERVIEW: un IntList è una lista modificabile // di Integer. // Elemento tipico [x1,...,xn] public IntList () { // EFFECTS: inizializza this alla lista vuota } public IntList (Integer x){ //REQUIRES: x e’ diverso da null // EFFECTS: se x e’ null solleva //NullPointerException, inizializza this alla //lista che contiene esattamente x }

Specifica di IntList public void addEl (Integer x) {//MODIFIES:this //REQUIRES: x e’ diverso da null // EFFECTS: se x e’ null solleva //NullPointerException, altrimenti aggiunge x //all’inizio di this } public Integer first (){ //REQUIRES: this non e’ vuota // EFFECTS:ritorna il primo elemento di this} public IntList rest (){ //REQUIRES: this non e’ vuota // ritorna la lista ottenuta da this togliendo //il primo elemento}

Specifica di IntList public int size () { // EFFECTS: ritorna il numero di elementi di //this} public String toString (){ //EFFECTS: restituisce una stringa che descrive //la sequenza di elementi di this } }

Come si implementa? Si puo’ implementare in tanti modi diversi (scegliendo opportune variabili d’istanza) Notiamo in ogni caso che il tipo di dato si puo’ usare utilizzando solo la specifica La specifica contiene tutte le informazioni che servono per usare il tipo di dato Programmando tramite la specifica astraiamo dalla particolare implementazione

Esempio: astrazione tramite specifica Il metodo rest restituisce il resto della lista (la lista meno il primo elemento) Usando first e rest si puo’ scorrere una lista (indipendentemente da come e’ implementata) Esempio: metodo di ricerca statico realizzato in un modulo (classe) separata public static boolean cerca (Intlist l,Integer x) throws NullPointerException{ //REQUIRES: l ed x diversi da null // EFFECTS: restituisce true se x occorre nella //lista l, false se non occorre}

Utilizzando solo la specifica public static boolean cerca (Intlist l,Integer x){ //caso base if (l.size()==0) {return false;} //caso ricorsivo {Integer el=l.first(); if (el.equals(x)) {return true;} return cerca(l.rest(),x);} }

Come si implementa? Dobbiamo scegliere delle variabili d’istanza che permettano di rappresentare sia la lista vuota che quella non vuota Deve essere possibile distinguere i due casi in modo chiaro private boolean vuota; //indica se e’ vuota private Integer val; //contiene il valore private IntList next; //puntatore al resto

Rappresentazione Lista val next vuota Lista vuota: any true Lista non vuota: any true 154 false 24 false

Nota Il flag vuota serve per indicare la lista vuota Nell’implementazione che facciamo quando vuota e’ falso garantiamo che il puntatore al resto della lista sia inizializzato (diverso da null) Semplifica l’implementazione dei metodi ricorsivi (non sono necessari test per vedere che il puntatore sia definito)

Costruttori public IntList () { // EFFECTS: inizializza this alla lista vuota vuota=true;} public IntList (Integer x) { // EFFECTS: inizializza this alla lista che contiene esattamente x vuota=false; val=x; next=new IntList();} Notate che nel secondo costruttore next viene inizializzato alla lista vuota (sta sempre alla fine, definizione ricorsiva) !

Costruttori val next vuota Lista vuota: any true Lista con un elemento: any true 24 false

Inserimento public void addEl (Integer x) { //MODIFIES:this // EFFECTS: aggiunge x all’inizio di this {if (vuota) {val=x;next=new IntList();vuota=false;} else {IntList n = new IntList(val); n.next = this.next; //copia di this this.val =x; this.vuota=false; this.next=n;} }} 4 Mettiamo l’elemento in testa, 4 creando un nuovo nodo che contiene x ed ha come resto 4 della lista this

First e rest public Integer first () { //REQUIRES: this non e’ vuota // EFFECTS: ritorna il primo elemento di this return val;} public IntList rest (){ //REQUIRES: this non e’ vuota // EFFECTS: ritorna la lista ottenuta da this //togliendo il primo elemento return next;}

Size e toString() public int size () { // EFFECTS: ritorna il numero di elementi di this if (vuota) return 0; return 1 + next.size(); } public String toString (){ // EFFECTS: ritorna una stringa che //descrive gli elementi di this String s=“”; if (vuota) {return s;} return val.intValue() + next.toString(); }

Esercizio I Definire una variante StringList Contiene Stringhe Ha un metodo d’istanza per aggiungere all’inizio ed alla fine, e per rimuovere una stringa data Ha un metodo d’istanza per cercare un elemento, ovvero una stringa data La rappresentazione deve essere realizzata da variabili private

Testing Il tipo di dato deve essere testato per verificare il funzionamento di costruttori e metodi Il testing va ovviamente implementato in un opportuno metodo main E’ conveniente dichiarare il metodo main in una classe separata (in modo da usare la classe che definisce le liste da un altro modulo) Nota: il metodo toString() utile per il testing Servirebbero comandi di input-output da tastiera e/o file

Esercizio 2 Implementare la seguente classe Classe che definisce alcune procedure statiche per manipolare liste di stringhe E’ una classe separata (non si vedono le variabili d’istanza della classe StringList)

public class IntListProc { // OVERVIEW: fornisce metodi statici per manipolare //liste di stringhe public static String min(StringList l) {// REQUIRES: l non e’ null e non e’ vuota //EFFECTS: restituisce il minimo elemento di l} public static StringList append (StringList l1, StringList l2) {// REQUIRES: l1 ed l2 non null //EFFECTS: restituisce una lista che e’ la //concatenazione di l1 ed l2. Ex: l1=[8,0], l2=[9] ===> [8,0,9]} public static void reverse(StringList l1) {// REQUIRES: l1 non null //MODIFIES:l1 //EFFECTS:modifica l1 invertendo l’ordine degli elementi} }

Esercizio II Vogliamo una variante di StringList Contiene Stringhe, ma ordinate in ordine crescente E’ possibile mantenere il tipo di dato ordinato? Basta modificare i costruttori ed i metodi d’istanza?