...

dispensa

by user

on
Category: Documents
9

views

Report

Comments

Description

Transcript

dispensa
PRINCIPI DELLA OOP
Ereditarietà e polimorfismo
Ereditarietà e specializzazione
Una delle caratteristiche distintive del paradigma di
programmazione orientato agli oggetti è l'ereditarietà
 L'ereditarietà permette di definire nuove classi mediante
l'aggiunta e/o la specializzazione di funzionalità ad altre
classi già esistenti oppure appositamente progettate e definite
Vedremo che questo meccanismo permette di:
 eliminare la duplicazione di codice (una classe che differisce
di qualcosa rispetto ad un'altra può sfruttare l'ereditarietà e
la specializzazione)
 introduce relazioni logiche tra classi

Giovanna Correddu – 07/04/2011
Ereditarietà - 1
Abbiamo già detto che ogni oggetto è riconducibile ad un’entità astratta
detta CLASSE. Tutti gli animali sono riconducibili alla classe Animale. Ogni
animale reale è un esemplare della classe Animale. La classe descrive le
proprietà e I comportamenti comuni a tutti gli esemplari della classe.

Proprietà


Nome
Comportamento

mangiare

muoversi

parlare (nel senso di emettere suoni)
Giovanna Correddu – 07/04/2011
Classe base Animale
4
Costruttore: inizializza lo stato di un
oggetto assegnando dei valori alle
proprietà
public class Animale {
private String nome;
public Animale(String nomeProprio) {
nome = nomeProprio;
}
public String getNome() {
return nome;
}
public void muoviti() {
………………………………
}
public void mangia() {
………………………………
}
Metodo d’accesso: restituisce il nome
dell’animale
Come si muove, come mangia e come
parla un animale generico?
public String parla() {
return "???”
//come parla un animale generico????;
}}
Giovanna Correddu – 07/04/2011
Fido e Cocorito - 1
5
Tra gli animali possiamo
avere cani, pappagalli e
altri con diverso
comportamento
Animale
Animale fido = new Animale(“Fido”);
Animale coco = new Animale(“cocorito”);
fido.muoviti();
fido.parla();
coco.muoviti();
coco.parla();
coco.mangia();
coco.muoviti();
fido.mangia()
fido.muoviti();
dovrebbe fare
baubau
dovrebbe dire
“mi chiamo
cooocorrito”
Fido e Cocorito sono entrambi animali, e quindi possono mangiare, muoversi e
parlare, ma non nello stesso modo. Come risolvere il problema??
Giovanna Correddu – 07/04/2011
Fido e Cocorito - 2
6
Posso creare due classi,
una classe Cane e una
classe Pappagallo
Cane
Pappagallo
Per entrambe le classi definisco gli stessi attributi e gli stessi metodi
Cane fido = new Cane(“Fido”);
Animale coco = new Animale(“cocorito”);
fido.muoviti();
fido.parla(); // baubau
coco.muoviti();
coco.parla(); // mi chiamo cooocorrito
fido.mangia()
fido.muoviti();
coco.mangia();
coco.muoviti();
Giovanna Correddu – 07/04/2011
Ereditarietà /2
7
Sia Fido che Cocorito sono animali

Essi hanno in comune attributi e metodi


nome

getNome()

mangia()

muoviti()

parla()
Si tratta degli stessi
attributi e metodi della
classe Animale!
Devo duplicarlo
in Cane e in
Papagallo??
Sarebbe molto comodo disporre di un meccanismo che consenta di riutilizzare
codice già scritto senza doverlo duplicare!

Questo meccanismo è previsto dalla programmazione orientata agli oggetti
ed è l’ereditarietà

Giovanna Correddu – 07/04/2011
Ereditarietà /3
8
Animale
Questo diagramma indica
che Cane e Pappagallo
derivano dalla classe
Animale dalla quale
ereditano attributi e
metodi; in Java si dice che
“estendono” la classe
Animale
-nome
+getNome()
+muoviti()
+mangia()
+parla()
Superclasse
Pappagallo
Cane
Classi derivate
Giovanna Correddu – 07/04/2011
Classe specializzata Cane
9
•
nella definizione delle classi derivate
scriviamo:
public class Cane extends Animale {
………..
public Cane(String nome) {
super(nome);
}
…………………..
}
public class Pappagallo extends Animale {
………..
public Pappagallo(String nome) {
super(nome);
}
…………………..
}
Giovanna Correddu – 07/04/2011
• Viene usata la parola
extends per derivare dalla
classe base Animale
• Il costruttore richiama
quello della classe base
tramite la parola riservata
super
• Stessa cosa per
Pappagallo
Relazioni / Specializzazione
10
•
•
•
Una classe si dice specializzazione di un'altra quando
deriva da essa
Cane o Pappagallo sono specializzazioni di Animale o
classi derivate
Animale è detta classe base o superclasse
Giovanna Correddu – 07/04/2011
Relazione “is a”
Una relazione di ereditarietà è espressa dalla frase
"E' un ...“ (is a)
Ad esempio:

Una giraffa è un animale.

Un cane è un animale.

Un aeroplano è un aeromobile;

Un elicottero è un aeromobile.
Animale è la superclasse o classe base; mentre giraffa e cane
sono le sottoclassi o classi derivate.
Aeromobile è la superclasse o classe base; mentre aeroplano
e elicottero sono le sottoclassi o classi derivate.
Giovanna Correddu – 07/04/2011
Test 1: si tratta di ereditarietà?
Fido è un cane.
E’ una relazione di ereditarietà?
Perché?
Giovanna Correddu – 07/04/2011
Risposta al test 1
No.
Fido non eredita da cane ma è un'istanza di
cane. Fido è un nome concreto e non astratto o
generico, in altri termini Fido è un oggetto e non
una classe. L'ereditarietà vale fra le classi. Per
cui non c'è nessuna ereditarietà.
Giovanna Correddu – 07/04/2011
Test 2: si tratta di ereditarietà?
Supponiamo di sviluppare
un’applicazione per gestire un
torneo di calcio.
Esiste ereditarietà derivata da
specializzazione tra le classi Squadra
e Giocatore?
Giovanna Correddu – 07/04/2011
Risposta al test 2
No.
Una Squadra è costituita da Giocatori, ma non
possiamo dire né che un giocatore sia una squadra, né
che la squadra sia un giocatore.
Per esserci ereditarietà tra due classi devo poter dire
che un’istanza della sottoclasse è anche istanza della
superclasse, nel senso in cui dico che un’istanza di Gatto
è anche istanza di Animale.
Quella tra Squadra e Giocatore è una relazione di
aggregazione (una squadra è costituita da giocatori)
Giovanna Correddu – 07/04/2011
Test 3 : si tratta di ereditarietà?
In generale, tra due classi
Padre e Figlio, esiste una
relazione di ereditarietà ?
Giovanna Correddu – 07/04/2011
Risposta al test 3
No.
Si può dire che Padre e Figlio
estendano entrambi la classe Persona
Giovanna Correddu – 07/04/2011
L’ereditarietà nel mondo reale



Per comprendere il concetto di ereditarietà possiamo
ricorrere a molti esempi tratti dal mondo reale.
Gli animali possono essere classificati in vertebrati e
invertebrati; i vertebrati possono essere a loro volta
classificati in mammiferi, rettili, pesci, uccelli, ecc... I
mammiferi possono essere cani, gatti, uomini, balene e così
via.
Ognuna di tali tipologie di animali possiede alcune
caratteristiche e funzionalità comuni (tutti gli animali si
riproducono, si nutrono, si muovono, ...) e altre che sono
strettamente proprie (ad esempio, solo i vertebrati hanno
una struttura ossea, solo i mammiferi allattano i loro piccoli,
soltanto l'uomo è in grado di parlare,...) .
Giovanna Correddu – 07/04/2011
L’ereditarietà nel mondo reale




ciascuna classe eredita da quella
superiore caratteristiche, funzioni e
comportamenti
ogni sottoclasse aggiunge
caratteristiche e comportamenti
specifici, non presenti nella classe
superiore, oppure specializza secondo
modalità proprie comportamenti
presenti anche nella classe superiore
specializzazione di comportamento:
tutti gli animali si muovono, ma ognuno
con modalità proprie
nuovo comportamento: i mammiferi
presentano il comportamento "Allattare
la prole" non presente negli altri
animali
Giovanna Correddu – 07/04/2011
Ereditarietà e polimorfismo/1
Torniamo ora al nostro esempio.
Cane e Pappagallo ereditano tutti gli attributi e i metodi della
classe base: nome, getNome(), parla(), muoviti(), mangia()
C’è però un problema:
•
•
•
•
•
•
Fido e Cocorito sono animali e quindi mangiano, si muovono e
parlano, ma non allo stesso modo!!!!
Fido quando parla fa “bau bau”
Cocorito dice “mi chiamo cooocorrito “
Anche il loro movimento è diverso e non mangiano lo stesso cibo
Sarebbe utile avere un meccanismo che mi consenta di ridefinire I
metodi, in modo da specializzarli per le due classi
Questo meccanismo è il polimorfismo
Giovanna Correddu – 07/04/2011
Override
public class Cane extends Animale {
………..
public Cane(String nome) {
super(nome);
}
public void parla() {
System.out.println(“io faccio baubau”);
}
public void mangia() {
System.out.println(“mangio le mie
crocchette!!”);}
}
public void muoviti() {
System.out.println(“mi muovo a quattro
zampe!!”);}
}
}
Giovanna Correddu – 07/04/2011
I metodi della classe base
sono stati ridefiniti, anche
se hanno conservato stesso
nome e stessa definizione
(parametri e restituzione)
Questo tipo di
polimorfismo è detto
override
Puoi fare qualcosa di
analogo anche per la
classe Pappagallo.
Prova da solo!!
Ereditarietà / 4
Quando una classe estende una superclasse :
 ne eredita gli attributi e i metodi
Inoltre può:
 definire nuovi attributi (per esempio per il cane possiamo
aggiungere l’attributo razza)
 definire nuovi metodi (per esempio per Cane possiamo
definire il metodo corri() non presente nella superclasse
 ridefinire metodi già presenti nella superclasse (override di
metodi)
Giovanna Correddu – 07/04/2011
Ereditarietà /5
23
•
Giovanna Correddu – 07/04/2011
Si parla di
gerarchia di oggetti
quando un oggetto
possiede dei
discendenti che a
loro volta ne hanno
altri (si pensi
all'albero
genealogico)
Polimorfismo /1
24
Permette di ridefinire il comportamento di un oggetto
 sia Fido che Cocorito hanno un metodo parla() ma il
risultato è un pò diverso...
 perchè cambia l’implementazione dei due metodi
(ovvero l’algoritmo relativo ai due metodi)

Giovanna Correddu – 07/04/2011
Polimorfismo / 2
Esistono più tipi di polimorfismo
• Overload – due o più metodi della stessa classe
hanno lo stesso nome ma prendono argomenti
diversi (lo abboamo già visto)
• Override – un metodo presente nella classe base
viene ridefinito in una o più classi derivate (è legato
all’ereditarietà)
• Polimorfismo dei riferimenti (anch’esso legato
all’ereditarietà)
Giovanna Correddu – 07/04/2011
Riferimenti polimorfi/ 1
26
•
Il polimorfismo permette di manipolare le classi derivate con lo
stesso puntatore o riferimento utilizzato per riferirsi alla classe
base
Cane bracco = new Cane("Braccobaldo");
Animale fido = new Cane("Fido");
System.out.println(fido.getNome()+
bracco.getNome());
• Alla seconda linea viene creato un oggetto Cane che viene riferito
con un puntatore di tipo Animale
• L'assegnazione è lecita perché Cane deriva da Animale
• Il contrario darebbe errore
Giovanna Correddu – 07/04/2011
Riferimenti polimorfi/2
27
•
•
•
Cosa succede se si vuole “convertire" un
oggetto Animale generico in una classe
derivata?
Se l'assegnazione è lecita, ovvero l'oggetto
generico è di tipo compatibile basta fare un
casting esplicito
Se l'assegnazione non è lecita viene generato
un errore a runtime (non a compile time)
Giovanna Correddu – 07/04/2011
Riferimenti polimorfi/3
28
Animale fido = new Cane("Fido");
Animale silvestro = new Gatto("Silvestro");
// fido e silvestro sono entrambi animali, ma fido è un cane,
mentre silvestro è un gatto
Gatto g=silvestro; //ERRORE tempo di compilazione!
//è errata perché silvestro è un riferimento di tipo animale: posso
però convertirlo in riferimento di tipo gatto eseguendo il casting
esplicito, nel seguente modo
Gatto g = (Gatto) silvestro; // e' corretto perché l’istanza
alla quale punta silvestro è di tipo gatto
// la seguente genera errore run time perché fido e' un
riferimento ad un oggetto di classe Cane
Gatto g1 = (Gatto)fido;
Giovanna Correddu – 07/04/2011
Operatore instanceof
29
•
E' possibile testare un oggetto per scoprire il suo tipo
utilizzando l'operatore instanceof
Animale fido = new Cane("Fido");
if (fido instanceof Gatto) {
System.out.println("Fido è un gatto");
} else if (fido instanceof Cane) {
System.out.println("Fido è un cane");
}
Giovanna Correddu – 07/04/2011
Classi e metodi astratte /1
30
•
•
•
•
•
All'inizio abbiamo definito la classe base Animale
con il metodo parla()
Questo metodo non ha nessuna utilità nella classe
base: non è infatti possibile scrivere un qualsiasi
algoritmo che produca un verso per la classe
Animale. Che verso fa il generico animale?
Forse parla() non è un metodo della classe base?
Eppure tutti gli animali parlano, per cui è
sicuramente un metodo della classe base.
Allo stesso modo possiamo chiederci: tutti gli
animali condividono il comportamento “muoversi”,
ma come si muove un generico Animale? Salta?
Striscia?
Giovanna Correddu – 07/04/2011
Classi e metodi astratti /2
•
•
•
•
Esiste un modo per dichiarare che una classe base ha metodi
che sono comuni a tutte le classi che da essa derivano
(muoversi, parlare, mangiare), ma questi metodi non possono
essere implementati nella classe base: sono metodi astratti
Saranno le classi derivate che dovranno implementare tutti
questi metodi astratti nel modo corretto
Una classe che presenta metodi astratti è detta classe
astratta
La classe astratta non può essere istanziata: è possibile
immaginare un’esemplare di un generico animale? Noi
riusciamo solo a immaginare un cane, un gatto, ….
Giovanna Correddu – 07/04/2011
Classi e metodi astratti /3
32
•
Si crea una classe con il metodo parla astratto
public abstract class Animale {
…………………..
…………………..
public abstract String parla(); //manca il corpo
public abstract String muoviti(); //manca il corpo
public abstract String mangia(); //manca il corpo
…………………………..
}
Giovanna Correddu – 07/04/2011
Classe Object /1
33
•
•
•
In Java tutte le classi hanno una classe base implicita
Questa classe di chiama Object e contiene dei metodi
utili alla Java Virtual Machine
Scrivere
public class Animale {
…………………….
}
• Equivale a scrivere
public class Animale extends Object {
………………………….
}
Giovanna Correddu – 07/04/2011
Classe Object /2
34
•
•
La classe Object e‘ la radice della gerarchia delle classi Java
Tra i metodi contenuti in Object troviamo equals e toString
public class Object {
// Verifica se due oggetti sono uguali
public boolean equals(Object obj) {
}
// Converte un oggetto in stringa
public String toString() {
}
}
Giovanna Correddu – 07/04/2011
Ereditarietà singola e interfacce /1
35
•
•
In Java si può derivare da una sola classe
Può essere necessario definire un nuovo oggetto con
caratteristiche provenienti da due oggetti diversi
•
•
•
Un pappagallo vola, un cane nuota
Un'anatra può sia volare che nuotare
Anche un aereo è un oggetto volante e una barca è un
natante
Giovanna Correddu – 07/04/2011
Ereditarietà singola e interfacce /2
36
•
•
•
•
•
•
•
In java non è ammessa l'ereditarietà multipla; l'anatra non può
estendere Animale, OggettiVolanti e OggettiNatanti
Si utilizzano le interfacce (parola riservata interface)
Le interface sono simili alle classi astratte
Esse hanno la dichiarazione dei metodi senza implementazione
Possono avere solo metodi pubblic
Non possono avere attributi
Le classi derivate implementano le interfacce
Giovanna Correddu – 07/04/2011
Interfacce/1
37
•
Le nostre classi diventano
public interface OggettiNatanti {
public boolean nuota();
}
public interface OggettiVolanti {
public boolean vola();
}
Giovanna Correddu – 07/04/2011
Interfacce/2
38
public class Cane extends Animale implements OggettiNatanti {
...
...
public boolean nuota() {
return true;
}
}
public class Pappagallo extends Animale implements
OggettiVolanti{
...
...
public boolean vola() {
return true;
}
}
Giovanna Correddu – 07/04/2011
Implementazione di interfacce
39
public class Anatra extends Animale implements OggettiVolanti,
OggettiNatanti{
...
...
public boolean nuota() {
return true;
}
public boolean vola() {
return true;
}
}
Giovanna Correddu – 07/04/2011
Esercizio 1.1
40
•
Scrivere la classe Pubblicazione avente come attributi:


•
•
•
•
titolo
editore
Scrivere i costruttori, con e senza parametri e i metodi getter e setter
Scrivere il metodo toString per restituire il valore degli attributi sotto
forma di stringa
Scrivere il metodo equals per verificare se l'oggetto corrente è uguale
ad uno passato come argomento (è restituito un boolean)
Scrivere la classe TestPubblicazione con il metodo main che crea due
pubblicazioni con dati inseriti da tastiera, le visualizza e verifica se sono
uguali
Giovanna Correddu – 07/04/2011
Esercizio 1.2
41
1)
2)
3)
Definire una classe Rivista derivata da Pubblicazione con attributo
specifico periodicità; ridefinire toString e equals
Definire una classe Libro derivata da Pubblicazione con attributo
specifico autore; ridefinire toString e equals
Definire una classe TestPubblicazioni che crea alcune istanze di
Rivista e di Libro con dati a scelta
Giovanna Correddu – 07/04/2011
Esercizio 2.1
Creare la gerarchia di classi:



Punto (con attributi le coordinate x e y)
Pixel (in più il colore)
Punto3D (in più la coordinata z)
Implementare le tre classi prevedendo per la classe Punto il
metodo costruttore, i metodi set, get e i metodi toString e
equals.
Aggiungere nella classe Pixel e Punto3D i metodi per la
gestione delle sottoclassi e ridefinire opportunamente i metodi
toString e equals . Commentare le classi indicando quali metodi
e quali attributi sono estesi, ereditati, ridefiniti.
Giovanna Correddu – 07/04/2011
Esercizio 2.2
1.
2.
3.
Creare due istanze qualsiasi di Punto3D
Visualizzare le coordinate dei due punti
Verificare se i due punti coincidono e visualizzare
opportuno messaggio
Giovanna Correddu – 07/04/2011
Fly UP