26
Programmazione II Lezione 18 Daniele Sgandurra [email protected] 11/1/2011 1/26 Programmazione II Lezione 18 11/1/2011

Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Programmazione IILezione 18

Daniele Sgandurra

[email protected]

11/1/2011

1/26 Programmazione II Lezione 18 11/1/2011

Page 2: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Sommario

1 JavaEreditarieta

2/26 Programmazione II Lezione 18 11/1/2011

Page 3: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java

Parte I

Java

3/26 Programmazione II Lezione 18 11/1/2011

Page 4: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Gerarchie dell’Ereditarieta

L’ereditarieta non si limita a un solo livello di classi:

ad esempio, una classe Executive che estende Manager:

Java non supporta l’ereditarieta multipla.

4/26 Programmazione II Lezione 18 11/1/2011

Page 5: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Polimorfismo (1)

Regola per decidere se usare o no l’ereditarieta nell’organizzazione dei

dati:

la regola “is-a” afferma che ogni oggetto di una sottoclasse e unoggetto della superclasse:

ogni manager e un impiegato.

ma non e vero il contrario:

ogni impiegato non e un manager.

Principo di sostituzione: si puo utilizzare un oggetto della sottoclasseogni volta che il programma si aspetta un oggetto della superclasse:

Employee e ;e = new Employee ( . . . ) ; //OKe = new Manager ( . . . ) ; //OK

5/26 Programmazione II Lezione 18 11/1/2011

Page 6: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Polimorfismo (2)

Le variabili oggetto sono polimorfiche: una variabile di tipo Employee puo fareriferimento a un oggetto di tipo Employee oppure a un oggetto di unasottoclasse di Employee (Manager, Secretary, Executive, etc.):

Manager boss = new Manager ( . . . ) ;Employee [ ] staff = new Employee [ 3 ] ;staff [ 0 ] = boss ;

Per il compilatore, staff[0] e un oggetto Employee, per cui e corretto:

boss . setBonus (5000) ; //OK

mentre invece non e corretto:

staff [ 0 ] . setBonus (5000) ; //ERRORE

in quanto il metodo setBonus() non e un metodo della classe Employee. Non sipuo assegnare un riferimento alla superclasse in una variabile di una sottoclasse:

Manager m = staff [ i ] ; // ERRORE

6/26 Programmazione II Lezione 18 11/1/2011

Page 7: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Polimorfismo (3)

In Java gli array dei riferimenti delle sottoclassi possono essere convertitisenza un cast. Ad esempio, se abbiamo,

Manager [ ] managers = new Manager [ 1 0 ] ;

possiamo convertirlo in un array di Employee:

Employee [ ] staff = managers ; //OK

Cosa succede se eseguiamo questa istruzione?

staff [ 0 ] = new Employee ( ” . . . ” ) ; //OK

7/26 Programmazione II Lezione 18 11/1/2011

Page 8: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Polimorfismo (4)

Il compilatore accetta la precedente assegnazione anche se sia staff[0]

che manager[0] puntano allo stesso oggetto (come se un impiegato fossetrattato come un manager), per cui poi non sarebbe corretto fare:

manager [ 0 ] . setBonus (1000) ; //NO

perche si accederebbe a una variabile d’istanza che non esiste.

Tutti gli array ricordano il tipo di elemento col quale sono stati creati econtrollano che vengano memorizzati solo riferimenti compatibili ad esso.

L’istruzione di assegnamento di un Employee a un array di managerprovoca (a run-time) l’eccezione ArrayStoreException.

8/26 Programmazione II Lezione 18 11/1/2011

Page 9: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Binding Dinamico (1)

Cosa succede quando si invoca un metodo su un oggetto?

1 Il compilatore cerca il tipo dichiarato dell’oggetto e il nome del metodo:

es., x.f(param) dove x e un oggetto della classe C;il compilatore enumera tutti i metodi di nome f delle classe C e tutti quellipublic di nome f nelle superclassi di C (i metodi candidati).

2 Il compilatore stabilisce i tipi dei parametri indicati nella chiamata del metodo:

risoluzione dell’overloading: si invoca il metodo i cui parametri coincidonocon quelli indicati.

3 Se il metodo e dichiarato private, static, final o e un costruttore, ilcompilatore sa quale metodo invocare: binding statico. Altrimenti, il metodo dachiamare dipende dal tipo effettivo del parametro implicito: binding dinamico.

4 In caso di binding dinamico, la macchina virtuale deve invocare il metodo

appropriato per il tipo effettivo di x:

se il tipo effettivo e D (sottoclasse di C), si cerca un metodo nella classe D

con quella firma, altrimenti si cerca nella superclasse di D e cosı via.

9/26 Programmazione II Lezione 18 11/1/2011

Page 10: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Binding Dinamico (2)

Nell’ultimo caso, sarebbe inefficiente effettuare la ricerca a run-time ogni voltache si chiama un metodo.

La macchina virtuale predispone per ciascuna classe una tabella dei metodi cheelenca tutte le firme dei metodi e i riferimenti ai metodi stessi.

Es.: se la chiamata fosse x.f(‘‘Hello’’) e il metodo effettivo di x e D, la

macchina virtuale controlla la tabella dei metodi per la classe D, di firma

f(String):

questo metodo puo essere D.f(String) o X.f(String) dove X e unadeterminata superclasse di D.

Se la chiamata fosse super.f(String) allora la macchina virtuale consulta latabella dei metodi della superclasse relativa al parametro implicito.

10/26 Programmazione II Lezione 18 11/1/2011

Page 11: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Binding Dinamico (3)

Tabella dei metodi della classe Employee:

getName ( ) −> Employee . getName ( )getSalary ( ) −> Employee . getSalary ( )getHireDay ( ) −> Employee . getHireDay ( )raiseSalary ( d o u b l e ) −> Employee . raiseSalary ( d o u b l e )

Tabella dei metodi della classe Manager:

getName ( ) −> Employee . getName ( )getSalary ( ) −> Manager . getSalary ( )getHireDay ( ) −> Employee . getHireDay ( )raiseSalary ( d o u b l e ) −> Employee . raiseSalary ( d o u b l e )setBonus ( d o u b l e ) −> Manager . setBonus ( d o u b l e )

Si supponga di invocare e.getSalary(), la macchina virtuale:

1 recupera la tabella dei metodi da usare in base al tipo effettivo di e, chepotrebbe essere Employee, Manager, etc;

2 cerca la firma getSalary() nella definizione della classe;3 invoca il metodo.

11/26 Programmazione II Lezione 18 11/1/2011

Page 12: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Binding Dinamico (4)

Proprieta fondamentale del binding dinamico:

i programmi sono estensibili senza bisogno di modifiche al codice.

Es.: se si aggiunge una nuova classe Executive e la variabile e di prima

puo riferirsi anche a un oggetto di questa classe, allora:

il codice che contiene la chiamata e.getSalary() non deve esserericompilato:il metodo Executive.getSalary() viene chiamatoautomaticamente qualora e faccia riferimento a un oggetto di tipoExecutive.

12/26 Programmazione II Lezione 18 11/1/2011

Page 13: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Esercizio 1

Si scriva la classe Executive, estendendo la classe Manager, aggiungendo una variabile

d’istanza sharesOfStock che indica la percentuale del capitale dell’azienda posseduta

dal manager. Per calcolare lo stipendio annuale, bisogna aggiungere allo stipendio il

prodotto del capitale dell’azienda (che puo essere una variabile di classe finale statica

di Executive) per sharesOfStock per una percentuale piccola (es., 0.001%, anche

questa una variabile finale statica). Bisogna fare l’override dei metodi quando

necessario. A questo punto, modificare il main dell’esercizio 2 lezione 15 per riempire

l’array di Employee con impiegati, manager o executive, facendo in modo che la

somma delle sharesOfStock di tutti gli oggetti Executive esistenti sia uguale a 100

(ad esempio, si puo usare una variabile privata statica di classe che tiene traccia delle

sharesOfStock gia assegnate, piu metodi per ritornare e modificare tale valore).

Infine, usando lo stesso codice gia scritto, stampare lo stipendio di tutti gli impiegati.

13/26 Programmazione II Lezione 18 11/1/2011

Page 14: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Classi e Metodi Finali

Scopo: evitare che si possa creare una sottoclasse di una classe esistente.

Le classi che non possono essere estese prendono il nome di classi finali:

si usa il modificatore di classe final, esempio:

f i n a l c l a s s Executive e x t e n d s Manager

{. . .

}

Anche i metodi possono essere specificati come final: in questo caso, nessunasottoclasse puo effettuare l’override di quel metodo, esempio:

c l a s s Employee

{. . .p u b l i c f i n a l String getName ( ){

r e t u r n name ;}. . .

}

Se una classe e dichiarata final, automaticamente tutti i metodi (ma non levariabili) sono definiti final.

14/26 Programmazione II Lezione 18 11/1/2011

Page 15: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Casting (1)

Procedura per forzare una conversione da un tipo a un altro. Es.:

d o u b l e x = 3 . 4 0 4 5 ;i n t y = ( i n t ) x ;

queste istruzioni convertono il valore di x in un intero, troncando la partefrazionaria.

Vale anche per gli oggetti:

Manager boss = ( Manager ) staff [ i ] ; //OK s e l a p o s i z i o n e i c o n t i e n e un ←↩r i f e r i m e n t o a un o g g e t t o Manager

Necessita di usare metodi specifici di una classe dopo che il tipo effettivoe stato dimenticato.

15/26 Programmazione II Lezione 18 11/1/2011

Page 16: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Casting (2)

Se si prova a fare il cast verso una sottoclasse:

Manager boss = ( Manager ) staff [ i ] ; //ERRORE s e l a p o s i z i o n e i c o n t i e n e ←↩un r i f e r i m e n t o a un o g g e t t o Employee

a run-time si puo generare un’eccezione ClassCastException.

Uso dell’operatore instanceof:

i f ( staff [ i ] i n s t a n c e o f Manager )boss = ( Manager ) staff [ i ] ;

Il compilatore rileva cast che non funzionano:

Date d = ( Date ) staff [ i ] ; //ERRORE : Date non e ’ s o t t o c l a s s e d i Employee

16/26 Programmazione II Lezione 18 11/1/2011

Page 17: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Classi Astratte (1)

Risalendo nella gerarchie, le classi diventano sempre piu generiche.

Ad esempio, estenendo la gerarchia della classe Employee si puoaggiungere una classe Person:

Utilita: vogliamo mettere in comune il metodo getName() di Employee eStudent.

Vogliamo anche aggiungere un metodo getDescription() per restituireuna descrizione della persona.

17/26 Programmazione II Lezione 18 11/1/2011

Page 18: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Classi Astratte (2)

Il metodo getDescription() e facilmente realizzabile per Employee e

Student, ma non per Person:

questa classe non sa nulla di una persona a eccezione del nome.

La soluzione e quella di utilizzare la parola chiave abstract che nonrichiede di implementare il metodo:

p u b l i c a b s t r a c t String getDescription ( ) ; // non r i c h i e s t a i m p l e m e n t a z i o n e

Per motivi di chiarezza, una classe con almeno un metodo astratto deveessere dichiarata astratta:

a b s t r a c t c l a s s Person

{. . .p u b l i c a b s t r a c t String getDescription ( ) ;

}

18/26 Programmazione II Lezione 18 11/1/2011

Page 19: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Classi Astratte (3)

Le classi astratte possono avere dati e metodi concreti. Esempio:

a b s t r a c t c l a s s Person

{p r i v a t e String name ;

p u b l i c Person ( String n ){

name = n ;}

p u b l i c a b s t r a c t String getDescription ( ) ;

p u b l i c String getName ( ){

r e t u r n name ;}

}

Quando si estende una classe astratta, ci sono due possibilita:

(i) si implementano tutti i metodi astratti;(ii) si lascia astratto qualche (o tutti) i metodi astratti della

superclasse: la sottoclasse rimane astratta.

19/26 Programmazione II Lezione 18 11/1/2011

Page 20: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Classi Astratte (4)

Una classe puo essere dichiarata abstract anche se non ha metodiastratti.

Non e possibile creare istanze di una classe astratta: ad esempio

new Person ( ” p ippo ” ) ; //ERRORE

genera un errore.

E possibile creare oggetti di sottoclassi concrete.

E possibile creare variabili oggetto di una classe astratta, ma devonoriferirsi a un oggetto di una sottoclasse concreta:

Person p = new Student ( ” Mario R o s s i ” , ” I n f o r m a t i c a ” ) ;

20/26 Programmazione II Lezione 18 11/1/2011

Page 21: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Esercizio 2

Si scriva la classe astratta Person e la classe concreta Student che ha una

variabile di istanza corsoLaurea (String) e un costruttore con due parametri

(il nome e il corso di laurea): il costruttore deve invocare il costruttore della

superclasse per settare il nome. Il metodo getDescription() ritorna una

stringa del tipo “uno studente del corso di laurea in ” + corsoLaurea. In

maniera analoga, modificare la classe Employee per estendere Person,

implementando il metodo getDescription() (che ritorna una stringa del tipo

“un impiegato con un salario di ” + salario) e modificando opportunamente il

costruttore. Infine, in maniera analoga all’esercizio precedente, creare una

classe di test in cui nel main si crea un array di Person per contenere Student

e Employee e alla fine, tramite un ciclo for-each, si stampa il nome e la

descrizione di ogni persona.

21/26 Programmazione II Lezione 18 11/1/2011

Page 22: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Accessi Protetti

Spesso, si vuole limitare l’accesso a un metodo alle sole sottoclassi oppure si

vuole permettere ai metodi della sottoclasse di accedere direttamente a una

variabile della superclasse:

in questo caso, si dichiara protected una certa parte della classe:

se la variabile hireDay di Employee e protected invece di private,allora i metodi di Manager possono accedervi direttamente (ma solosu oggetti Manager, non su oggetti Employee).

raramente si usa l’attributo protected per le variabili: modifiche allasuperclasse possono avere impatto sulle sottoclassi (contrario allo spiritodei linguaggi orientati agli oggetti);i metodi possono essere dichiarati protetti se sono “difficili” da utilizzare:metodi utilizzabili solo dalle sottoclassi (che sanno come) e non le altre.

Modificatori di accesso:

visibile solo alla classe (private);visibile a tutti (public);visibile al pacchetto e a tutte le sottoclassi (protected);visibile al pacchetto (di default: senza parole chiave).

22/26 Programmazione II Lezione 18 11/1/2011

Page 23: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

La Classe Object

La classe Object e il livello principale di tutte le classi:

in Java, ogni classe estende (di default) Object;superclasse predefinita da cui si eredita se non diversamente specificato.

E possibile usare una variabile di tipo Object per fare riferimento a oggetti diqualsiasi tipo:

Object obj = new Employee ( ‘ ‘ . . . . ’ ’ ) ;

Per fare qualcosa di specifico con la variabile, occorre conoscere il tipo originalee applicare il cast:

Employee e = ( Employee ) obj ;

Solo i tipi primitivi (int, char, boolean, ...) non sono oggetti.

Tutti i tipi di array sono classi che estendono Object:

Employee [ ] staff = new Employee [ 1 0 ] ;obj = staff ; //OKobj = new i n t [ 1 0 ] ; //OK

23/26 Programmazione II Lezione 18 11/1/2011

Page 24: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Alcuni Metodi Della Classe Object

La classe Object definisce dei metodi (molti sono utili quando si usano i thread):

p u b l i c b o o l e a n equals ( Object obj )

Le sottoclassi possono fare l’override di questo metodo se vogliono definire un metodoche verifica l’uguaglianza tra due oggetti.

p u b l i c String toString ( )

Ritorna una rappresentazione in stringa dell’oggetto. Ad esempio, viene usatoautomaticamente dalla JVM per convertire un riferimento a un oggetto in String:

Employee e = new Employee ( ‘ ‘ . . . . ’ ’ ) ;System . out . println ( e ) ;

Infine:

p u b l i c i n t hashCode ( )

ritorna il codice hash, che e un intero ricavato da un oggetto che lo “caratterizza”.

24/26 Programmazione II Lezione 18 11/1/2011

Page 25: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Esercizio 3

Modificare l’esercizio precedente effettuando l’ovveride di toString delle classiEmployee e Student per ritornare una rappresentazione dell’oggetto sottoforma di stringa (es., per un impiegato: descrizione piu data di assunzione): seoggetti di sottoclassi (es., Student e Employee) usano rappresentazioni simili(cioe, hanno qualcosa in comune, come la descrizione), bisogna fattorizzare ilcodice nel metodo toString della superclasse comune (es., Person) econcatenarlo alle parti specifiche. Alla fine, quando si stampano gli oggetticontenuti nell’array di Person, modificare il codice inserendo direttamente ilriferimento agli oggetti nella println (es., System.out.println(p)).

25/26 Programmazione II Lezione 18 11/1/2011

Page 26: Programmazione II - Lezione 18 - unipi.itgroups.di.unipi.it/~daniele/teaching/pr2-10/pr2-18.pdf · 2011. 1. 11. · Java Ereditariet a Gerarchie dell’Ereditariet a L’ereditariet

Java Ereditarieta

Riferimenti

[1] Core Java 2. Vol. 1: Fondamenti (Cap. 5).

Horstmann Cay S., Cornell Gary.

26/26 Programmazione II Lezione 18 11/1/2011