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

Slides:



Advertisements
Presentazioni simili
Programmazione ad oggetti
Advertisements

Argomenti della lezione
3TC – 5/11/2010 Cicli while e do.. While Contatori e Totalizzatori.
Java: programmazione concorrente con condivisione di memoria
1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
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.
Metodologie di Programmazione = decomposizione basata su astrazioni
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.
1 Metodologie di Programmazione. 2 Contenuto generale §tecniche per la programmazione orientata ad oggetti (in piccolo) §esemplificate utilizzando il.
Algoritmi in C++ (1) da completare
1 Corso di Informatica (Programmazione) Lezione 12 (19 novembre 2008) Programmazione in Java: i metodi statici.
Astrazioni sul controllo Iteratori. 2 Nuove iterazioni Definendo un nuovo tipo come collezione di oggetti (p. es., set) si vorrebbe disporre anche di.
Specifiche senza JML: uso delle asserzioni. 2 Asserzioni in Java Dal jdk 1.4 (da Febbraio 2002) cè meccanismo per gestire asserzioni Asserzione: espressione.
eliana minicozzi linguaggi1a.a lezione2
Dichiarazione di classi Programmazione Corso di laurea in Informatica.
Selezione (=scelta) con “if-else”
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.
Le classi Definizione di classe Attributi e metodi di una classe Costruttori e distruttori Private e public Funzioni friend Il puntatore this.
Java Collections.
AN FI Un denominatoe comune Linguaggi di programmazione Un denominatore comune.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Enumerazioni e Classi 1. Enumerazioni Permettono di definire nuovi tipi che consistono in un insieme di valori costanti (ognuno con un nome) – Migliorano.
Passaggio di parametri per indirizzo
Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 9 Tipi parametrici Collezioni generiche. Strutture matematiche parametriche.
Ricerca sequenziale in un array di interi
Astrazione procedurale ed eccezioni
Oggetti in C# Lezione 1 Classi ed istanze Oggetti in C# - Lezione 1.
Nota (rif. alla lezione precedente): Vector vs ArrayList Le classi generiche Vector e ArrayList sono sostanzialmente equivalenti, ma: I metodi.
Esercitazione Ereditarietà Polimorfismo. Entita’ Geometrica PuntoCerchioPoligono TriangoloQuadrilatero Rettangolo Quadrato.
Polimorfismo Significato Significato Varie famiglie Varie famiglie Polimorfismo in java Polimorfismo in java Polimorfismo di Sottotipo: Apparato in Java.
Fondamenti di informatica Oggetti e Java Luca Cabibbo Luca Cabibbo – Fondamenti di informatica: Oggetti e Java Copyright © 2004 – The McGraw-Hill Companies.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Programmazione I - corso B a.a prof. Viviana Bono Blocco 7 – Array.
Astrazione di dati Dati Astratti: cosa e perchè Dati Astratti: due meccanismi differenti Dati Astratti: due meccanismi differenti Astrazione e incapsulamento.
1 Tipi di Dato §descrittori, tipi, controllo e inferenza dei tipi §specifica (semantica) e implementazione di tipi di dato l implementazioni “sequenziali”
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 non vogliamo definire versioni differenti dell’astrazione corrispondente ad una collezione di elementi.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Primo Compitino Primo esercizio Identificare gli errori segnalati dal compilatore Verifica statica del codice Regole di binding per i nomi (quelle.
1 Progettazione dettagliata di un Tipo di Dato Astratto: l’ambiente di metodi.
Specifiche. Scopo e significato delle specifiche (1) Lo scopo di una specifica è di definire il comportamento di un ’ astrazione. Gli utenti si baseranno.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
1 Astrazione sul controllo: gli iteratori. 2 Gli iteratori 4 perché vogliamo iterarare “in modo astratto” 4 iteratori e generatori in Java –specifica.
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.
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 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.
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.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
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.
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.
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.
1 Tipi di dato modificabili §a livello semantico, riconduciamo la modificabilità alla nozione di variabile l lo stato “modificabile” corrispondente sarà.
Ese 3 (del 3 Aprile 2003).
Transcript della presentazione:

Astrazioni Polimorfe e Tipi Generici

2 Polimorfismo Dal Greco molte forme Una variabile polimorfa può riferirsi a oggetti di classi diverse Un metodo polimorfo può avere parametri di tipi diversi Un tipo polimorfo può essere un contenitore di dati di tipi diversi (per esempio stack di oggetti di tipo qualunque…)

3 Polimorfismo Polimorfismo per procedure e iteratori: astrazioni parametriche rispetto al tipo di uno o piu` argomenti –Es. e motivazione: invece di costruire una procedura di ordinamento per un vettore di interi, una per per un vettore di stringhe, ecc.,è preferibile unica astrazione procedurale che ordina un vettore, e che sia utilizzabile sia per gli interi che per le stringhe, Polimorfismo per data abstraction: astrazione parametrica rispetto a tipo degli elementi contenuti negli oggetti –Es. Invece di unastrazione per insiemi di numeri interi (IntSet) e una per insiemi di stringhe (StrSet), preferibile unica astrazione del concetto di insieme (astrazione Set) utilizzabile sia per gli interi che per le stringhe

4 Esempio: Ricerca sequenziale …. public static int cerca(Object x, Vector a) { x != null && a !=null && (\forall int i; 0<=i<a.size(); a.get(i)!=null); \result == -1 && (*non esiste in a elemento equals a x *) || x.equals(a.get(\result)) for(int i=0; i<a.size(); i++) { if(x.equals(a.get(i)) return i; return –1; } Il codice per Object è unastrazione di quello, ad esempio, per int. Similmente, si potrebbe definire cerca(Object, Iterator ) o cerca(Object, Collection ) per astrarre ricerca sequenziale a qualunque contenitore

5 Es. Specifica di set polimorfo public class PolimSet { // OVERVIEW: PolimSet sono insiemi mutabili illimitati // oggetto null non può appartenere a un oggetto PolimSet // usato equals per determinare uguaglianza di elementi public Polim Set()// costruttore public void insert (Object x) throws NullPointerException {…} signals x == null ensures x!=null && (*inserisce x (non un suo clone) in this *) public void remove (Object x) public boolean IsIn (Object x) public boolean subset ( Polim Set s) }

6 Implementazione (parziale) di PolimSet public class PolimSet{ private ArrayList els; //oppure Vector public PolimSet(){els=new ArrayList();} // oppure Vector() public void insert (Object x) throws NullPointerException { if (getIndex(x) < 0) els.add(x); } private int getIndex(Object x){ for(int i=0; i<els.size(); i++) if(x.equals(els.get(i)) return i; return –1; } public void remove (Object x){ if (x==null) return; els.remove(x); } public boolean IsIn (object x){…} public boolean subset (PolimSet s){…} }

7 Attenzione allimplementazione del metodo equals Appartenenza di un elemento a oggetto PolimSet determinata usando equals, quindi anche contenuto di un PolimSet dipende da esso Spesso (ad es. per Vector e tutte le classi delle librerie Sun) equals restituisce true se due vettori hanno lo stesso stato: attenzione a immettere oggetti Vector in un PolimSet! PolimSet s = new PolimSet(); Vector x = new Vector(); Vector y = new Vector(); s.insert(x); s.insert(y); x.add(new Integer(3)); if(s.isIn(y)) // qsta condizione vale false Questo può essere inatteso (dopo s.insert(y); senza un remove ci si aspetta che y sia ancora in s) –soluzione insoddisfacente: usare == invece di equals : non funziona per oggetti immutabili (es: due stringhe identiche nello stesso PolimSet) –Soluzione: racchiudere elementi (es. Vector) che si vogliono distinguere in oggetti di una classe contenitore (wrapper) che ridefinisca il metodo equals in maniera opportuna y non viene aggiunto a causa di equals

8 Usare un contenitore per gli oggetti mutabili della collezione public class Container{ private Object el; public Container(Object x){el = x;} public Object get () {return el;} public boolean equals (Object x){ if(! x instanceOf Container) return false; return (el == ((Container) x).get()); } Adesso il codice (con qualche modifica) funziona come ci aspettiamo Polim Set s = new Polim Set(); Vector x = new Vector(); Vector y = new Vector(); s.insert(new Container(x)); s.insert(new Container(y)); x.add(new Integer(3)); if(s.isIn(new Container (y))) // condizione vera

9 Accorgimenti nelluso di collezioni polimorfe Le collezioni polimorfe (e.g., PolimSet) sono definite rispetto a elementi di classe Object, quindi –bisogna incapsulare (wrap) i tipi primitivi: int Integer –i metodi osservatori che restituiscono elementi della collezione restituiranno oggetti di tipo Object, quindi occorre fare il casting e nel caso di tipi primitivi estrarre (unwrap) –a volte wrap e unwrap evitati grazie ad autoboxing e autounboxing PolimSet s = new PolimSet(); s.insert(new Integer(3)); … … … Iterator g = s.elements(); while (g.hasNext()){ int i = (Integer) g.next(); //NB: autounboxing … … } incapsulamento del tipo primitivo casting

10 Problema con astrazioni polimorfe Il vincolo che gli elementi di una collezione siano tutti dello stesso tipo non può essere controllato dal compilatore! quindi possono verificarsi errori di classe a run-time (che non si verificano, e.g., con IntSet). Esempio List myIntList = new LinkedList(); // 1 myIntList.add(new Integer(0)); // 2 Integer x = (Integer) myIntList.iterator().next(); // 3 –Il cast in linea 3 è noioso: il programmatore sa cosa cè nella lista. –Se pero la riga (2) fosse: myIntList.add(new String(0)); // 2 –allora loggetto restituito in linea 3 non sarebbe un Integer, causando un errore run time! Come fare a evitarlo? Noi vorremmo type safety! Questo è un problema ineliminabile fino al JDK 1.4 incluso, in quanto è necessario usare il casting Risolto in Java 1.5 con i tipi generici

11 Classi Generiche Generici forniscono unastrazione sui tipi, simile alle astrazioni polimorfe ma più sicure (type-safety è sempre garantita) –Esempio di lista di interi con i generici List myIntList = new LinkedList (); // 1 myIntList.add(new Integer(0)); //2 Integer x = myIntList.iterator().next(); // 3 –alla riga 3non serve più il cast: il compilatore sa che la lista contiene solo oggetti Integer –se la riga 2 fosse: myIntList.add(new String(0)); // 2 –non ci sarebbe bisogno di mandare in esecuzione il programma per accorgersi dellerrore: ce lo segnalerebbe il compilatore

12 Classi Generiche Esempi di classi generiche: le interfacce List e Iterator - parti tra parentesi angolate sono parametri formali della classe generica; tipico identificatore: singola lettera maiuscola -List e Iterator sono invocazioni della classe generica, con parametro attuale Integer -NB: non si crea una classe nuova (nessuna duplicazione di codice) così come non si crea nuovo codice quando si invoca un metodo passandogli i parametri attuali public interface List { void add(E x); Iterator iterator(); } public interface Iterator { E next(); boolean hasNext(); } public interface IntegerList { void add(Integer x) Iterator iterator(); }

13 Genericità e Sottotipi Attenzione: alcune cose sembrano andare contro lintuizione Domanda fondamentale: una lista di String è una lista di Object? –NO! Altrimenti tramite una variabile lista di Object si può inserire un Object in una lista di String e quando si tenta di estrarre, tramite una variabile lista di String, un oggetto String, si verifica un errore In generale, se Gen è una classe generica e se ClassB è sottoclasse di ClassA allora Gen NON è sottoclasse di Gen (NB: a maggior ragione una lista di Object NON è sottoclasse di una lista di String) List ls = new ArrayList (); List lo = ls; lo.add(new Object()); String s = ls.get(0); // ERRORE: tenta di assegnare un Object a una String! // ERRORE IN COMPILAZIONE

14 Genericità e Sottotipi: i tipi jolly (1) Rimane problema di definire sottoclassi di classi ottenute per invocazione di classi generiche, per realizzare polimorfismo, e.g., nei metodi che hanno parametri contenitori Esempio: un metodo che stampi tutti gli elementi di una collezione –Non va: parametro attuale deve essere stesso tipo o sottotipo, ma Collection non ha alcun sottotipo nessun polimorfismo Occorre definire il tipo supertipo di tutte le collezioni ottenute per invocazione di Collection –questo è Collection (leggi: Collection di sconosciuto) void printCollection(Collection c) { for (Object e : c) { System.out.println(e);} } void printCollection(Collection c) { for (Object e : c) { System.out.println(e);} }

15 Genericità e Sottotipi: i tipi jolly (2) Linserzione di elementi NON è possibile! Collection c; c = new ArrayList (); c.add(new Object()); // errore di compilazione –NB: il tipo statico di c dice che il tipo dellelemento della collezione è sconosciuto (può essere qualsiasi) tipo del parametro attuale di add deve essere sottotipo di qualsiasi altro tipo non esiste tale tipo; unico valore attuale ammissibile è null –NB: è comunque possibile fare una c.get() e assegnare il risultato a una variabile di tipo Object, perchè qualsiasi cosa estratto dalla get è un Object.

16 Tipi jolly limitati Ad esempio –Per definire un metodo drawAll che accetti liste di qualsiasi sottotipo di Shape public void drawAll(List shapes) {... } è un esempio di jolly limitato –Rappresenta un tipo sconosciuto, di cui si sa che estende Shape –Shape è il suo limite superiore (upper bound) Solito problema con gli inserimenti public void addRectangle(List shapes) { shapes.add(0, new Rectangle()); // Errore: shapes di fatto // è in sola lettura } –perchè il tipo del componente del parametro shapes è un sottotipo sconosciuto di Shape: non è garantito che sia un supertipo di Rectangle classe Shape

17 Metodi Generici (1) Es: Metodo che travasa tutti gli oggetti di un array in una collezione static void fromArrayToCollection(Object[] a, Collection c) { for (Object o : a) { c.add(o); } } –Non funziona: Perchè? static void fromArrayToCollection(Object[] a, Collection c) { for (Object o : a) { c.add(o); } } –Non funziona neanche questo: Perchè? Il modo giusto è usare metodi generici, che hanno uno o più parametri che rappresentano tipi. static void fromArrayToCollection(T[] a, Collection c) { for (T o : a) { c.add(o); } } –per rendere corretta linserzione c.add(o) dobbiamo chiamare fromArrayToCollection con parametri in cui il tipo dellelemento della collezione sia supertipo di quello dellarray –NB: non occorre indicare esplicitamente parametri attuali in corrispondenza ai parametri formali di un metodo generico: ci pensa il compilatore a inferire il tipo del parametro attuale scegliendo il tipo più specifico (il minimo, nellordinamento tra tipi definito dalla gerarchia di ereditarietà, tra tutti quelli che rendono legale linvocazione del metodo generico)

18 Metodi Generici (2) Esempi di inferenza dei tipi da parte del compilatore String[] sa = new String[100]; Collection cs = new ArrayList (); fromArrayToCollection(sa, cs);// T inferred to be String Collection co = new ArrayList (); fromArrayToCollection(sa, co);// T inferred to be Object Integer[] ia = new Integer[100]; fromArrayToCollection(ia, cs);// compile-time error: String NON è supertipo di Integer

19 Metodi generici vs jolly (1) Possono apparire intercambiabili: interface Collection { public boolean containsAll(Collection c); public boolean addAll(Collection c); } interface Collection { public boolean containsAll(Collection c); public boolean addAll(Collection c); } Quale dei due stili è preferibile? Notiamo che –Nei due metodi il parametro T compare una sola volta, non vincola il valore restituito dal metodo e gli altri parametri del metodo –T serve solo per il polimorfismo, ma per questo basterebbero i tipi Jolly –I metodi generici servono per esprimere dipendenze tra gli argomenti del metodo oppure tra gli argomenti e il tipo restituito

20 Metodi generici vs jolly (2) Possibile anche luso combinato dei due class Collections { public static void copy(List destinazione, List sorgente){...} } alternativamente, senza tipi jolly class Collections { public static void copy(List dest, List src){...} }