ereditarietà e polimorfismo
DESCRIPTION
Ereditarietà e polimorfismoTRANSCRIPT
LEZIONE DI SILVANO NATALIZI DEL 23 NOVEMBRE 2008
PER LA CLASSE IVA LICEO TECNICO
Ereditarietà e polimorfismo
Albero di ereditarietà per un programma di simulazione di animali
1 quali sono gli attributi e i comportamenti comuni?
Ci è chiesto di disegnare un programma di simulazione che permetta agli utenti di giocare con tanti animali differenti nel loro ambiente per vedere che cosa succede.
Vogliamo anche che altri programmatori possano aggiungere in ogni momento altri tipi di animali al programma
Che cosa hanno i sei tipi di animali, cane, gatto, volpe, ippopotamo, leone, tigre, in comune ?
Quale è la relazione tra questi sei tipi ?Ogni animale sarà rappresentato da un oggettoQuesti oggetti si muoveranno in un ambiente,
facendo tutto quello che è permesso dalla programmazione di ciascun tipo.
Caratteristiche comuni
Variabili d’istanza: Immagine Cibo (carne, erba) Fame Confini ambiente Posizione (dell’animale)
Metodi fareRumore() - il parlare degli animali mangiare() dormire() muoversi()
2) Disegnare una classe che rappresenti lo stato e il comportamento comune
Disegniamo una super classe AnimaleInseriamoci tutte le variabili e i metodi di cui
tutti gli animali possano avere bisogno
3) Decidere se una classe necessita di comportamenti specifici
Non tutti gli animali mangiano e parlano al medesimo modo
Per cui decidiamo di (override) sovrascrivere i metodi mangiare() e fareRumore() nelle singole sottoclassi
4) cerchiamo altre opportunità di usare l’astrazione per trovare altri elementi
comuni
Guardiamo alle sottoclassi e troviamo che la volpe e il cane hanno comportamenti comuni; lo stesso dicasi per il leone, la tigre e il gatto. I primi appartengono alla razza canina gli altri a quella felina
Possiamo usare le famiglie biologiche per organizzare le classi degli animali e in questo caso creiamo una classe Canina super classe di Volpe e Cane; e creiamo una classe Felina super classe di Gatto Tigre Leone
5) Completiamo la gerarchia delle classi
Decidiamo che la classe Canina ha in comune il metodo muoversi() e che anche la classe Felina ha in comune un proprio metodo muoversi().
Quale metodo è chiamato ?
La classe Volpe ha 4 metodi; dormire() ereditato da Animale; muoversi() ereditato da Canina fareRumore() e mangiare() sovrascritti
Quando si crea un oggetto volpe e lo si assegna ad una variabile, si usa l’operatore punto . Per invocare l’esecuzione dei 4 metodi. Ma quale versione di questi metodi viene chiamata ?
Il più basso vince !
Volpe v=new Volpe(); v.fareRumore(); v.muoversi() v.mangiare(); v.dormire();
Il criterio is-a, has-a
Quando una classe eredita da un’altra diciamo che extends la super classe.
Quando vogliamo sapere se una cosa possa estenderne un’altra, applichiamo il criterio di test is-a ossia è un
Un triangolo è una forma Un gatto è un felino
Un lavandino estende un gabinetto ?
Applichiamo il test is-a, un lavandino è un bagno ? Decisamente NO!
Rovesciamo il test, un bagno è un lavandino ? NO!
Bagno e lavandino sono correlati, ma dalla relazione has-a, ossia un bagno ha un lavandino
Ciò significa che Bagno ha una variabile di tipo Lavandino, ossia un riferimento a Lavandino, ma non lo estende e viceversa.
Ma c’è di più !
Il criterio di test is-a lavora ovunque nell’albero di ereditarietà.
If class B extends class A, class B is-a class AIf class C extends class B, class C supera il
test is-a sia per la classe B che per quella A.Canina extends Animale
Volpe extends Canina Volpe extends Animale
Canina è un Animale Volpe is-a Canina
Volpe is-a Animale
Di più di più
Finchè Animale è da qualche parte nella gerarchia di ereditarietà al di sopra di Volpe, la Volpe è un Animale sarà sempre vero !
Questa struttura di ereditarietà dice al mondo: “la Volpe è una Canina, pertanto può fare tutto quello che
un Canino fa. “la Volpe è un Animale, pertanto può fare tutto quello che
un’animale fa.Non fa differenza se la Volpe ridefinisce alcuni
metodi di Animale o CaninaPer il mondo esterno al nostro codice, una Volpe
può eseguire i quattro metodi; non importa come lo faccia o dove.
1) Evitare codice duplicato
Metti il codice comune in un unico luogo, lascia che le sottoclassi ereditino il codice della super classe.
Quando vuoi cambiare questo codice lo devi modificare in un solo posto e tutti gli altri vedranno la variazione
Magicamente quella variazione si riflette in tutte le classi che ereditano quel comportamento
Devi solo ricompilare la super classeNon devi assolutamente ricompilare o comunque
toccare le sottoclassi !
2) Definire un protocollo comune per un gruppo di classi
La ereditarietà garantisce che tutte le classi, raggruppate sotto un determinato supertipo, abbiano tutti i suoi metodi. Quando definisci un metodo in una super classe, che
può essere ereditato da tutte le sue sottoclassi, stai annunciando un tipo di protocollo “tutti i miei sottotipi possono fare queste cose, con questi metodi che assomigliano a questo…”
In altre parole si stabilisce un contratto Un protocollo o contratto è un insieme di regole che ci
si accorda di seguire e rispettare.
Polimorfismo piccola introduzione
Cane mioCane= new Cane();La precedente dichiarazione avviene in tre tempi:1) Cane mioCane dice a java di allocare spazio in
memoria per una variabile di riferimento di tipo Cane. In altre parole crea un telecomando che ha dei bottoni per controllare un Cane, non un Gatto o altro
2) new Cane() dice a java di allocare dello spazio in memoria per un nuovo oggetto Cane
3) = assegna il nuovo oggetto Cane alla variabile di riferimento mioCane; in altre parole programma il telecomando per selezionare il canale Cane.
Polimorfismo 2
Il punto importante della questione è che il tipo della variabile di riferimento e il tipo dell’oggetto creato siano i medesimi !
In questo esempio entrambi sono di tipo CaneMa con il polimorfismo
Il riferimento e l’oggetto possono essere di diversi tipo Animale mioCane=new Cane();
Il tipo del riferimento può essere il tipo di una super classe dell’oggetto creato
Polimorfismo 3
Quando si dichiare una variabile di riferimento, ogni oggetto che supera il test is-a per il tipo dichiarato, può essere assegnato a quel riferimento.
In altre parole, ogni cosa che estende il tipo di variabile dichiarata può essere ad essa assegnata.
Esempio polimorfismo
Animale[] animali=new Animale[5]; abbiamo dichiarato un array di animali che può quindi
memorizzare oggetti di tipo Animale Ma guarda cosa possiamo fare:
animali[0]=new Cane();animali[1]=new Gatto();animali[2]=new Volpe();animali[3]=new Ippopotamo();animali[4]=new Leone();
Possiamo mettere un qualsiasi oggetto delle sottoclassi nell’array animali !
Esempio polimorfismo
Inoltre potete scorrere tutti gli elementi dell’array e richiamare i metodi della classe Animale ed ogni oggetto fa la cosa che deve fare !
For (int i=0; i<animali.lenght;i++){ animali[i].mangiare(); animali[i].muoversi();
}
Class Vet { public void visita(Animale a){
// a.fareRumore();
} } Il parametro a Animale
può assumere qualsiasi tipo di animale come argomento e quando il veterinario dice ad un animale di fareRumore(), sarà eseguito il metodo del tipo di animale sotto cura!
Class AnimaleOwner{ Public void start(){
Vet ve=new Vet(); Cane ca=new Cane(); Leone le=new
Leone(); ve.visita(ca); ve.visita(le);
}
}
Esempio polimorfismo