La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Esercitazione del 7 marzo 2008 Ereditarieta’. Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro.

Presentazioni simili


Presentazione sul tema: "Esercitazione del 7 marzo 2008 Ereditarieta’. Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro."— Transcript della presentazione:

1 Esercitazione del 7 marzo 2008 Ereditarieta’

2 Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro

3 public class Libro{ //OVERVIEW: un Libro memorizza il titolo (String), //l’autore (String), numero di copie (int) //la rappresentazione private String titolo; private String autore; private int copie; public Libro(String t,String a,int n){ //REQUIRES: n >0 //EFFECTS: crea un nuovo Libro con titolo t, //autore a, e numero di copie n titolo=t; autore=a; copie =n;} public void somma(int num) { //REQUIRES: num>0 //MODIFIES:this //EFFECTS: aggiorna il numero delle copie sommando //num copie =copie + num;} }

4 public String autore(){ //EFFECTS: restituisce l’autore di this return autore;} public String titolo(){ //EFFECTS: restituisce il titolo di this return titolo;} public int copie(){ //EFFECTS: restituisce il numero di copie di this return copie;} public boolean equals(Libro p){ //EFFECTS: restituisce true se this e p // sono uguali, altrimenti false if (autore.equals(p.autore) && titolo.equals(p.titolo) && copie.equals(p.copie))return true else return false;} }

5 Esempio Libro l1=new Libro(“DC”,”Dante”,1); Libro l2=new Libro(“DC”,”Dante”,1); l1==l2=======> false l1.equals(l2) =====>true

6 public class ProcLibro{ //OVERVIEW: definisce metodi statici per //effettuare operazioni su un array di Libri public static boolean cerca(Libro[] b, Libro p){ //EFFECTS: restituisce true se p occorre in b, //altrimenti false } public static String cerca-titolo(Libro[] b, String a){ //EFFECTS: restituisce il titolo di un Libro //appartenente a b con autore a, se non ce ne // sono la stringa vuota} public static int all-copie (Libro[] b, String a, String t){ //EFFECTS: restituisce il numero di copiein b del //Libro che ha autore a e titolo t } }

7 public class ProcLibro{ //OVERVIEW: definisce metodi statici per //effettuare operazioni su un array di Libri public static boolean cerca(Libro[] b, Libro p){ //EFFECTS: restituisce true se p occorre in b, //altrimenti false for (int i=0; i <b.lentgh,i++) {if (b[i].equals(p))return true; } return false; } public static String cerca-titolo(Libro[] b, String a){ //EFFECTS: restituisce il titolo di un Libro //appartenente a b con autore a, se non ce ne // sono la stringa vuota String result=“”; for (int i=0; i <b.lentgh,i++) {if (b[i].autore().equals(a)) result=b[i].titolo();} return result; }

8 public static int all-copie(Libro[] b, String a, String t){ //EFFECTS: restituisce il numero di copie in b del //Libro che ha autore a e titolo t int numero=0; for (int i=0; i< a.length; i++) {if (b[i].titolo().equals(t) && b[i].autore().equals(a)) numero=numero+ b[i].copie(); } return numero; } NOTA: i metodi della classe ProcLibro sono indipendenti dalla implementazione di Libro Usiamo Libro in base alla sua interfaccia pubblica

9 Esercitazione di oggi Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio di Sostituzione

10 Se c1 è una sottoclasse di (estende) c2 le variabili e metodi statici di c2 (e delle sue superclassi) sono visibili direttamente da c1 variabili e metodi di istanza di c2 (e delle sue superclassi) diventano anche variabili e metodi di istanza di c1 (a meno di overriding) Ereditarieta’

11 Una sottoclasse puo’ sovrascrivere un metodo della superclasse (stesso nome, stessi parametri, stesso tipo) In tal caso sugli oggetti della sottoclasse viene utilizzato il metodo sovrascritto (quello piu’ specifico) Overriding

12 Anche per i costruttori esiste un meccanismo di ereditarietà se c1 e’ sottoclasse di c2 all’atto della creazione di una istanza di c1 si esegue automaticamente il costruttore (senza parametri) di c2 (per inizializzare le variabili ereditate) Costruttori

13 Esercizio 1 Sia dia l’implementazione del seguente tipo di dato Persona

14 public class Persona { //OVERVIEW: una Persona e’ caratterizzata dal nome //(una stringa) e dall’indirizzo (una stringa) public Persona(String nome,String indirizzo) { //EFFECTS: costruisce una nuova Persona con nome // nome ed indirizzo indirizzo} public String getNome() { //EFFECTS: restituisce il nome di this } public String getIndirizzo() { //EFFECTS: restituisce l’indirizzo di this } public String toString() { //EFFECTS: restituisce una stringa che riporta nome ed //indirizzo di this } public boolean equals(Persona p) { //EFFECTS: restituisce true sse this e’ uguale a p } }

15 Implementazione La rappresentazione deve essere privata (e.g. variabili d’istanza private) Attenzione al metodo equals, deve confrontare lo stato interno dei due oggetti e non il riferimento

16 Esercizio II Si definisca una sottoclasse Studente di Persona le istanze di Studente sono caratterizzate oltre che dal nome e dall’indirizzo, anche dal numero di matricola (un intero)

17 Metodi e Costruttori Il costruttore, prende come parametro il nome e l’indirizzo ed il numero di matricola inoltre, vogliamo un metodo aggiuntivo public int getMatricola(){ //EFFECTS: restituisce la matricola di this }

18 Cosa fare? Progettare la specifica della classe: intestazione classe=====> costruttori + metodi + descrizione informale

19 Dopo la specifica Scegliere le variabili d’istanza adatte a rappresentare lo stato interno Implementare i metodi di conseguenza

20 Specifica di una sottoclasse Deve contenere costruttori e metodi aggiuntivi rispetto alla superclasse Deve contenere i metodi overridden (se necessario) E’ utile ereditare il piu’ possibile

21 Esempio: specifica costruttore public Studente(String n,String i, int m) { //EFFECTS: costruisce un nuovo Studente con nome // n e indirizzo i e numero di matricola m}

22 Metodi d’istanza Quali metodi possono essere ereditati? Quali devono essere sovrascritti?

23 Metodi della superclasse public String getNome() { //EFFECTS: restituisce il nome di this } public String getIndirizzo() { //EFFECTS: restituisce l’indirizzo di this } FUNZIONANO CORRETTAMENTE!

24 Metodi della superclasse public String toString() { //EFFECTS: restituisce una stringa che riporta nome ed //indirizzo di this } NON E’adeguato =========> OVERRIDING

25 toString() di Studente public String toString() { //EFFECTS: restituisce una stringa che riporta nome ed //indirizzo e numero di matricola di this } Overriding: dobbiamo dichiarare lo stesso metodo (stessa intestazione), specializzandone specifica ed l’implementazione

26 Metodi della superclasse public boolean equals(Persona p) { //EFFECTS: restituisce true sse this e’ uguale a p } Il parametro e’ di tipo Persona Il metodo confronta lo stato interno di this con quello del parametro p

27 Se non lo sovrascrivo public boolean equals(Persona p) { //EFFECTS: restituisce true sse this e’ uguale a p } La sottoclasse Studente lo eredita Il parametro e’ di tipo Persona (lo posso usare con un parametro di ogni sottotipo)

28 Esempio Persona p1=new Persona(“Fra”,”Pisa”); Studente s1=new Studente(“Elodie”,”Pisa”,1); Studente s2=new Studente(“Elodie”,”Pisa”,2); Posso chiamarlo per confrontare uno studente ed una persona s1.equals(p1)====> false Posso chiamarlo per confrontare due studenti s1.equals(s2)====> true In entrambi i casi confronta solo nome ed indirizzo

29 Per contro Studente s1=new Studente(“Elodie”,”Pisa”,1); Studente s2=new Studente(“Elodie”,”Pisa”,2); Vorrei s1.equals(s2)====> false Differiscono per il numero di matricola Come si risolve il problema?

30 Soluzione I:overriding public boolean equals(Persona p) {//REQUIRES: p di tipo Studente //EFFECTS: restituisce true sse this e’ uguale a p (ha stesso nome, indirizzo e numero di matricola) } Precondizione richiede che il parametro sia del sottotipo (altrimenti la post-condizione non avrebbe senso) Puo’ essere usato solo per confrontare due Studenti

31 Esempio Studente s1=new Studente(“Elodie”,”Pisa”,1); Studente s2=new Studente(“Elodie”,”Pisa”,2); Abbiamo s1.equals(s2)====> false Viene selezionato il metodo della sottoclasse perche’ this e’ di tipo Studente (metodo piu’ specifico)

32 Svantaggio della soluzione Non abbiamo garanzia del fatto che equals sovrascritto sia di tipo Studente (chi lo usa potrebbe sbagliare) E’ sempre conveniente che un metodo sovrascritto funzioni per tutti gli inputs per cui funzionava il metodo della superclasse Deve esserci sempre una relazione tra la specifica di una sottoclasse e quella di una superclasse (lo vedremo ad MP)

33 Soluzione II:overloading //metodo nuovo nella sottoclasse public boolean equals(Studente p) { //EFFECTS: restituisce true sse this e’ uguale a p (ha stesso nome, indirizzo ) } Puo’ essere usato solo per confrontare due Studenti Dichiariamo un nuovo metodo nella sottoclasse

34 Overloading Nella classe Studenti avremmo due metodi equals METODO EREDITATO: public boolean equals(Persona p) { //EFFECTS: restituisce true sse this e’ uguale a p } METODO NUOVO: public boolean equals(Studente p) { //EFFECTS: restituisce true sse this e’ uguale a p } L’interprete sceglie quale eseguire in base al tipo del parametro

35 Esempio Persona p1=new Persona(“Fra”,”Pisa”); Studente s1=new Studente(“Elodie”,”Pisa”,1); Studente s2=new Studente(“Elodie”,”Pisa”,2); Se il parametro e’ del supertipo usa quello ereditato s1.equals(p1)====> false Se il parametro e’ del sottotipo usa quello nuovo s1.equals(s2)====> false Soluzione migliore: la scelta la fa l’interprete e non il programmatore

36 Attenzione: implementazione Il costruttore di Studente deve assegnare i valori a tutte le variabili (nuove ed ereditate) Ereditarieta’ del costruttore: automatica solo per quello di default (senza parametri) Invece nella superclasse il costruttore chiede dei parametri

37 Problema Variabili della superclasse sono private Bisogna usare costruttori e metodi della superclasse (tramite super) Alternativa protected

38 Principio di Sostituzione Un oggetto del sottotipo può essere utilizzato dovunque sia richiesto un oggetto del supertipo Un oggetto di tipo Studente puo’ essere usato ovunque sia richiesto un oggetto di tipo Persona Per capire questo concetto scriviamo del codice che usa il supertipo Persona

39 Esercizio III Vogliamo realizzare un Archivio Memorizza informazioni su un insieme di persone (oggetti di tipo Persona) di dimensione fissata Vogliamo che nell’insieme non ci siano ripetizioni

40 Specifica I public class Archivio { //OVERVIEW: un Archivio e’ un insieme di Persona // senza ripetizioni di dimensione fissa public Archivio(int dim) {//REQUIRES: dim >0 //EFFECTS: costruisce un nuovo Archivio vuoto //di dimensione dim} public String toString() { //EFFECTS: restituisce una stringa che descrive l’insieme //di persone contenute in this }

41 Specifica II public String cercan(String indirizzo) { //EFFECTS: restituisce il nome di una Persona con indirizzo indirizzo che occorre in this, altrimenti restituisce la stringa vuota } public String cercai(String nome) { //EFFECTS: restituisce l’indirizzo di una Persona con nome nome che occorre in this, altrimenti restituisce la stringa vuota }

42 Specifica III: modificatori public boolean insert(Persona p) { //MODIFIES: this //EFFECTS: se p non occorre gia’ in this e ci sono ancora posizioni libere lo inserisce e restituisce true, altrimenti restituisce false } public boolean remove(Persona p) { //MODIFIES: this //EFFECTS: se p appartiene a this lo rimuove e restituisce true, altrimenti restituisce true } }

43 Implementazione Per rappresentare lo stato di un archivio puo’ usare un array di Persona La dimensione dell’array viene fissata al momento della creazione dell’archivio E’ utile memorizzare la prima posizione dell’array che e’ libera

44 Implementazione Nei metodi di inserimento e rimozione per confrontare due oggetti Persona usare equals (al solito) Le variabili d’istanza che implementano lo stato devono essere private Altrimenti non possiamo garantire che non ci siano ripetizioni

45 Testing Archivio e’ definito per il supertipo Persona Puo’ memorizzare oggetti di un qualsiasi sottotipo (ex Studente)

46 Nel main Studente x1=new Studente(“Fra”,”Pisa”, 12); Studente x2=new Studente(“Fra”,”Pisa”,13); Archivio a= new Archivio(5); boolean c=a.insert(x1); boolean c= a.insert(x2); Per confrontare studenti a run-time viene scelto il metodo equals piu’ specifico: quello overriden della sottoclasse ! Quello della superclasse non e’ adatto (differiscono solo per il numero di matricola)


Scaricare ppt "Esercitazione del 7 marzo 2008 Ereditarieta’. Esercizio: soluzione Implementare la seguente specifica che definisce un tipo di dato Libro."

Presentazioni simili


Annunci Google