La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo.

Presentazioni simili


Presentazione sul tema: "Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo."— Transcript della presentazione:

1 Alcune Classi Standard Object, Vettori

2 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

3 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

4 Classe Object La classe Object è la superclasse, diretta o indiretta, di ciascuna classe in Java Object è supertipo di qualsiasi oggetto (a parte come vedremo per alcuni tipi primitivi)

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

6 A cosa serve? Grazie al meccanismo dell'ereditarietà  i suoi metodi sono ereditati da tutti i tipi (che definiscono oggetti).  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 In particolare: assegnamento e/o passaggio dei parametri

7 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

8 Sono metodi ereditati da tutti i sottotipi 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

9 Commenti a toString() La definizione del metodo nella classe Object restituisce una stringa che contiene il nome della classe dell'oggetto su cui il metodo è invocato 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

10 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

11 Per capire meglio l’importanza di Object Vediamo come permetta di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object 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.)

12 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

13 Specifica (alcuni metodi) 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 Ci sono anche altri costruttori tipo quelli degli arrays che permettono di creare un vettore vuoto ma con una certa capacita’ (dato numero di posizioni allocate ma vuote). Serve solo per avere implementazioni piu’ o meno efficienti (per ora lo ignoriamo)

14 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){ \\EFFECTS\\EFFECTS: sostituisce obj all'oggetto della posizione index} Se index e’ fuori dal size del vettore viene sollevata una eccezione come per gli arrays Metodi simili a quelli dell’array

15 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

16 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

17 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]

18 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……..

19 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 tipo restituito dal metodo (il suo tipo apparente) i metodi della classe Vector restituiscono valori di tipo Object. Necessario l’uso del Cast

20 Uso del 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 Cast potrebbe provocare un errore a run-time qualora il valore restituito dal metodo non fosse sottotipo di String

21 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…

22 La soluzione Ogni tipo ha un corrispondente involucro di 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

23 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

24 Esempio Per memorizzare il valore 3 in un Vector bisogna creare un Integer che contiene il valore Integer e= new Integer(3); //lo creo elements.addElement(e); //lo inserisco Per leggere un valore da un Vector di Integer e trasformarlo in int Integer i= (Integer) elements.elementAt(3); //Cast int x= i.intValue();//conversione

25 Esercizio Proposto Definire una classe VectorOp che definisce alcune procedure stand-alone (metodi statici) che operano su Vector contenenti Integer Il fatto che un Vector contenga Integer non e’ intrinseco nel tipo di dato (va messa una precondizione)

26 Metodi Statici public static int min(Vector v){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce il minimo di v o zero se il vettore e’ vuoto } Nota: dobbiamo mettere una precondizione sui dati di input (altrimenti non ha senso)

27 Metodi Statici:non modificatori public static Vector inc(Vector v, int i){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce un vettore che contiene tutti gli elementi di v (nello stesso ordine) incrementati di i} public static Vector reverse(Vector v){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce un vettore che e’ l’inverso di v} public static Vector sort(Vector v){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce un vettore che e’ una versione ordinata di v}

28 Metodi Statici: modificatori public static void remove(Vector v, int i){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\MODIFIES: v \\EFFECTS\\EFFECTS: rimuove da v tutte le occorrenze di x}

29 Sviluppare (in parallelo) un Tester Prende dei valori da console Costruisce un vettore che li contiene Testa i vari metodi, chiamandoli sul vettore Per “vedere” il contenuto di un vettore nelle varie fasi basta stampare tutti i suoi elementi Non fatelo alla fine (se no non serve a niente) Scrivete un metodo e testatelo (poi passate a quello successivo) Per i metodi che restituiscono un Vector e’ essenziale stampare i valori contenuti nel vettore

30 Importanza dei commenti informali Descrivono quello che vogliamo che un metodo o tipo di dato faccia Sono fondamentali (oltre che per spiegarvi cosa dovete fare negli esercizi) Mettetevi dal punto di vista di chi deve usare il metodo inc che avete implementato E’ pensabile che debba andare a leggere il codice per sapere cosa fa? Per vedere quale algoritmo avete usato? Se dovete usare un metodo della classe primitiva Vector andate a vedere l’implementazione o leggete nel manuale la descrizione del suo comportamento? I commenti informali servono quindi per informare chi lo usa di cosa il metodo fa (non di come lo fa ) e sono tutto quello che sanno sul funzionamento del metodo coloro che lo usano Procedendo in questo modo (lo vedremo ad MP) saranno un meccanismo di astrazione fondamentale (permettono di astrarre dalle varie implementazioni)

31 Soluzione public static Vector reverse(Vector v){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce un vettore che e’ l’inverso di v} Vector nuovo=new Vector(); for (int i=v.size()-1; i >=0;i++) { nuovo.addElement(v.elementAt(i));} return nuovo;} }

32 public static Vector sort(Vector v){ \\REQUIRES\\REQUIRES: v contiene Integer non null \\EFFECTS\\EFFECTS: restituisce un vettore che e’ la versione ordinata di v} Vector nuovo=new Vector(); for (int i=0; i< v.size();i++) {Integer x=(Integer) v.elementAt(i); boolean inserito=false; for (int j=0; j< nuovo.size();j++) {Integer h=(Integer) nuovo.elementAt(j)); if (x.intValue() < h.intValue()) {inserito=true; nuovo.insertElementAt(j,x);} } if (! inserito) {nuovo.addElement(x);} } return nuovo;} } Conviene creare un nuovo vettore in cui ricopiare i valori di v (invece che in ordine casuale in modo che sia ordinato) Se ne troviamo uno piu’ grande lo inseriamo al suo posto (vengono tutti spostati di una posizione) Se non lo abbiamo trovato allora o il vettore e’ vuoto o e’ il piu’ grande di tutti (va in fondo) }


Scaricare ppt "Alcune Classi Standard Object, Vettori. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo."

Presentazioni simili


Annunci Google