© M. Badella G. Malnati L. Tessitore, 2003-05
Ereditarietà
e
polimorfismo
Programmazione
ad Oggetti
A.A. 2004-05
© M. Badella G. Malnati L. Tessitore, 2003-05
Argomenti della lezione
I concetti principali
Ereditarietà in Java
La classe Object
Classi astratte
e interfacce
Programmazione ad Oggetti
2
© M. Badella G. Malnati L. Tessitore, 2003-05
Riusare il software
 A volte si incontrano classi con funzionalità simili
 In quanto sottendono concetti semanticamente “vicini”
 Una mountain bike assomiglia ad una bicicletta tradizionale
 È possibile creare classi disgiunte replicando le
porzione di stato/comportamento condivise
 L’approccio “Taglia&Incolla”, però, non è una strategia
vincente
 Difficoltà di manutenzione correttiva e perfettiva
 Meglio “specializzare” codice funzionante
 Sostituendo il minimo necessario
Programmazione ad Oggetti
3
© M. Badella G. Malnati L. Tessitore, 2003-05
Ereditarietà
 Meccanismo per definire una nuova classe (classe
derivata) come specializzazione di un’altra (classe
base)
 La classe base modella un concetto generico
 La classe derivata modella un concetto più specifico
 La classe derivata:
 Dispone di tutte le funzionalità (attributi e metodi) di quella
base
 Può aggiungere funzionalità proprie
 Può ridefinirne il funzionamento di metodi esistenti
(polimorfismo)
Programmazione ad Oggetti
4
© M. Badella G. Malnati L. Tessitore, 2003-05
Esempio
Bicicletta
coppia
rapportoPosteriore
…
pedala(coppia)
cambiaRapporto(n)
frena(intensità)
…
MountainBike
rapportoAnteriore
cambiaRapportoAnt(n)
Programmazione ad Oggetti
Tandem
coppia2
pedala2(coppia)
5
© M. Badella G. Malnati L. Tessitore, 2003-05
Terminologia
Classe base,
superclasse
Bicicletta
MountainBike
Tandem
Classi derivate,
sottoclassi
Programmazione ad Oggetti
6
© M. Badella G. Malnati L. Tessitore, 2003-05
Astrazione
 Il processo di analisi e progettazione del software di
solito procede per raffinamenti successivi
 Spesso capita che le similitudini tra classi non siano colte
inizialmente
 In una fase successiva, si coglie l’esigenza/opportunità di
introdurre un concetto più generico da cui derivare classi
specifiche
 Processo di astrazione
 Si introduce la superclasse che “astrae” il concetto comune
condiviso dalle diverse sottoclassi
 Le sottoclassi vengono “spogliate” delle funzionalità comuni
che migrano nella superclasse
Programmazione ad Oggetti
7
© M. Badella G. Malnati L. Tessitore, 2003-05
Veicolo
double getVelocità()
double getAccelerazione()
…
Bicicletta
void pedala()
Programmazione ad Oggetti
Automobile
void avvia()
void spegni()
8
© M. Badella G. Malnati L. Tessitore, 2003-05
Tipi ed ereditarietà
 Ogni classe definisce un tipo:
 Un oggetto, istanza di una sotto-classe, è formalmente
compatibile con il tipo della classe base
 Il contrario non è vero!
 Esempio
 Un’automobile è un veicolo
 Un veicolo non è (necessariamente) un’automobile
 La compatibilità diviene effettiva se
 I metodi ridefiniti nella sotto-classe rispettano la semantica
della superclasse
 L’ereditarietà gode delle proprietà transitiva
 Un tandem è un veicolo (poiché è una bicicletta, che a sua
volta è un veicolo)
Programmazione ad Oggetti
9
© M. Badella G. Malnati L. Tessitore, 2003-05
Vantaggi dell’ereditarietà
Evitare la duplicazione
di codice
Permettere il riuso
di funzionalità
Semplificare la costruzione
di nuove classi
Facilitare la manutenzione
Garantire la consistenza delle interfacce
Programmazione ad Oggetti
10
© M. Badella G. Malnati L. Tessitore, 2003-05
Ereditarietà in Java
Si definisce una classe derivata attraverso la
parola chiave “extends”
 Seguita dal nome della classe base
Gli oggetti della classe derivata sono, a tutti
gli effetti, estensioni della classe base
 Anche nella loro rappresentazione in memoria
Programmazione ad Oggetti
11
© M. Badella G. Malnati L. Tessitore, 2003-05
Ereditarietà in Java
Veicolo.java
public class Veicolo {
private double velocità;
private double accelerazione;
public double getVelocità() {…}
public double getAccelerazione() {…}
}
public class Automobile
Automobile.java
extends Veicolo {
private boolean avviata;
public void avvia() {…}
}
Programmazione ad Oggetti
12
© M. Badella G. Malnati L. Tessitore, 2003-05
Ereditarietà in Java
Automobile a=
new Automobile();
Memoria
velocità: 0.0
accelerazione: 0.0
a
Programmazione ad Oggetti
avviata: false
13
© M. Badella G. Malnati L. Tessitore, 2003-05
Meccanismi
Costruzione di
oggetti di classi
derivate
Accesso alle
funzionalità della
superclasse
Ri-definizione di
metodi
Programmazione ad Oggetti
14
© M. Badella G. Malnati L. Tessitore, 2003-05
Costruzione
Per realizzare un’istanza di una classe
derivata, occorre – innanzi tutto – costruire
l’oggetto base
 Di solito, provvede automaticamente il
compilatore, invocando – come prima operazione
di ogni costruttore della classe derivata – il
costruttore anonimo della superclasse
 Si può effettuare in modo esplicito, attraverso il
costrutto super(…)
 Eventuali ulteriori inizializzazioni possono essere
effettuate solo successivamente
Programmazione ad Oggetti
15
© M. Badella G. Malnati L. Tessitore, 2003-05
Esempio
class Impiegato {
String nome;
double stipendio;
Impiegato(String n) {
nome = n;
stipendio= 1500; class Funzionario
extends Impiegato {
}
}
Funzionario(String n) {
super(n);
stipendio = 2000;
}
}
Programmazione ad Oggetti
16
© M. Badella G. Malnati L. Tessitore, 2003-05
Accedere alla superclasse
L’oggetto derivato contiene tutti i
componenti (attributi e metodi) dell’oggetto
da cui deriva
 Ma i suoi metodi non possono operare
direttamente su quelli definiti privati
La restrizione può essere allentata:
 La super-classe può definire attributi e metodi
con visibilità “protected”
 Questi sono visibili alle sottoclassi
Programmazione ad Oggetti
17
© M. Badella G. Malnati L. Tessitore, 2003-05
Ridefinire i metodi
Una sottoclasse può ridefinire metodi
presenti nella superclasse
A condizione che abbiano
 Lo stesso nome
 Gli stessi parametri (tipo, numero, ordine)
 Lo stesso tipo di ritorno
 (La stessa semantica!)
Per le istanze della sottoclasse, il nuovo
metodo nasconde l’originale
Programmazione ad Oggetti
18
© M. Badella G. Malnati L. Tessitore, 2003-05
Ridefinire i metodi
class Base {
int m() {
return 0;
}
}
class Derivata
extends Base {
int m() {
return 1;
}
}
Base b= new Base();
System.out.println(b.m());
Derivata d= new Derivata();
System.out.println(d.m());
Programmazione ad Oggetti
19
© M. Badella G. Malnati L. Tessitore, 2003-05
Ridefinire i metodi
A volte, una sottoclasse vuole “perfezionare”
un metodo ereditato, non sostituirlo in toto
 Per invocare l’implementazione presente nella
super-classe, si usa il costrutto
super.<nomeMetodo> ( … )
class Base {
int m() {
return 0;
}
}
Programmazione ad Oggetti
class Derivata
extends Base {
int m() {
return super.m()+ 1;
}
}
20
© M. Badella G. Malnati L. Tessitore, 2003-05
Compatibilità formale
Un’istanza di una classe derivata è
formalmente compatibile con il tipo della
super-classe
 Base b = new Derivata( );
Il tipo della variabile “b” (Base) limita le
operazioni che possono essere eseguite
sull’oggetto contenuto
 Anche se questo ha una classe più specifica
(Derivata), in grado di offrire un maggior numero
di operazioni
 Altrimenti viene generato un errore di
compilazione
Programmazione ad Oggetti
21
© M. Badella G. Malnati L. Tessitore, 2003-05
Compatibilità formale
C
print()
D
print()
reset()
Programmazione ad Oggetti
C v1= new C();
C v2= new D();
D v3= new D();
v1.print() 
v2.print() 
v2.reset() 
v3.reset() 
22
© M. Badella G. Malnati L. Tessitore, 2003-05
Polimorfismo
class Base {
int m() {
return 0;
}
}
class Derivata
extends Base {
int m() {
return 1;
}
}
Base b= new Derivata();
System.out.println(b.m());
Programmazione ad Oggetti
23
© M. Badella G. Malnati L. Tessitore, 2003-05
Polimorfismo
Java mantiene traccia della classe effettiva
di un dato oggetto
 Seleziona sempre il metodo più specifico…
 …anche se la variabile che lo contiene
appartiene ad una classe più generica!
Una variabile generica può avere “molte
forme”
 Contenere oggetti di sottoclassi differenti
 In caso di ridefinizione, il metodo chiamato
dipende dal tipo effettivo dell’oggetto
Programmazione ad Oggetti
24
© M. Badella G. Malnati L. Tessitore, 2003-05
Polimorfismo
Per sfruttare questa tecnica:
 Si definiscono, nella super-classe, metodi con
implementazione generica…
 …sostituiti, nelle sottoclassi, da implementazioni
specifiche
 Si utilizzano variabili aventi come tipo quello della
super-classe
Meccanismo estremamente potente e
versatile, alla base di molti “pattern” di
programmazione
Programmazione ad Oggetti
25
© M. Badella G. Malnati L. Tessitore, 2003-05
Esempio
Forma
area()
perimetro()
Cerchio
Rettangolo
area()
perimetro()
area()
perimetro()
Programmazione ad Oggetti
Forma f1 =
new Cerchio();
Forma f2 = new
Rettangolo();
double d1,d2;
d1=f1.area();
d2=f2.area();
26
© M. Badella G. Malnati L. Tessitore, 2003-05
La classe java.lang.Object
In Java:
 Gerarchia di ereditarietà semplice
 Ogni classe ha una sola super-classe
Se non viene definita esplicitamente una
super-classe, il compilatore usa la classe
predefinita Object
 Object non ha super-classe!
Programmazione ad Oggetti
27
© M. Badella G. Malnati L. Tessitore, 2003-05
Metodi di Object
 Object definisce un certo numero di metodi
pubblici
 Qualunque oggetto di qualsiasi classe li eredita
 La loro implementazione base è spesso minimale
 La tecnica del polimorfismo permette di ridefinirli
 public boolean equals(Object o)
 Restituisce “vero” se l’oggetto confrontato è identico (ha lo
stesso riferimento) a quello su cui viene invocato il metodo
 Per funzionare correttamente, ogni sottoclasse deve fornire
la propria implementazione polimorfica
Programmazione ad Oggetti
28
© M. Badella G. Malnati L. Tessitore, 2003-05
Metodi di Object
 public String toString()
 Restituisce una rappresentazione stampabile dell’oggetto
 L’implementazione base fornita indica il nome della classe
seguita dal riferimento relativo all’oggetto
(java.lang.Object@10878cd)
 public int hashCode()
 Restituisce un valore intero legato al contenuto dell’oggetto
 Se i dati nell’oggetto cambiano, deve restituire un valore
differente
 Oggetti “uguali” devono restituire lo stesso valore, oggetti
diversi possono restituire valori diversi
 Utilizzato per realizzare tabelle hash
Programmazione ad Oggetti
29
© M. Badella G. Malnati L. Tessitore, 2003-05
Controllare l’ereditarietà
 In alcuni casi, si vuole impedire esplicitamente
l’utilizzo della tecnica del polimorfismo
 Ad esempio, per motivi di sicurezza o per garantire il
mantenimento di una data proprietà del sistema
 Si utilizza la parola chiave “final”
 Un metodo “final” non può essere ridefinito da una
sottoclasse
 Una classe “final” non può avere sottoclassi
 Un attributo “final” non può essere modificato
 Non c’entra nulla con l’ereditarietà!
Programmazione ad Oggetti
30
© M. Badella G. Malnati L. Tessitore, 2003-05
Controllare l’ereditarietà
In altri casi si vuole obbligare l’utilizzo del
polimorfismo
 Si introducono metodi privi di implementazione
 Facendoli precedere dalla parola chiave
“abstract”
Una classe che contiene metodi astratti
 Deve essere, a sua volta, dichiarata abstract
 Non può essere istanziata direttamente
 Occorre definire una sottoclasse che fornisca
l’implementazione dei metodi mancanti
Programmazione ad Oggetti
31
© M. Badella G. Malnati L. Tessitore, 2003-05
Classi astratte
abstract class
Base {
abstract int m();
}
class Derivata
extends Base {
int m() {
return 1;
}
}
Base b= new Derivata();
System.out.println(b.m());
Programmazione ad Oggetti
32
© M. Badella G. Malnati L. Tessitore, 2003-05
Interfacce
 Una classe astratta può contenere metodi non
astratti
 A beneficio delle proprie sottoclassi
 In alcuni casi, si vogliono definire metodi astratti
senza vincolare la gerarchia di ereditarietà delle
classi che li implementeranno
 Si utilizzano le interfacce:
 Insiemi di metodi astratti e costanti (attributi static final)
 Pubblici per definizione
 Una classe può implementare un’interfaccia
 Fornendo il codice relativo a tutti i metodi dichiarati
nell’interfaccia
Programmazione ad Oggetti
33
© M. Badella G. Malnati L. Tessitore, 2003-05
Esempio
public interface Comparable {
public int compareTo(Object o);
}
public class Rettangolo extends Forma
implements Comparable {
public int compareTo(Object o) {
//codice relativo…
}
//altri attributi e metodi…
}
Programmazione ad Oggetti
34
© M. Badella G. Malnati L. Tessitore, 2003-05
Interfacce e tipi
Analogamente alle classi, ogni interfaccia
definisce un tipo
 Un oggetto che implementa una data interfaccia
ha come tipo anche il tipo dell’interfaccia
 Un oggetto può implementare molte interfacce
 Di conseguenza può avere molti tipi
Si può verificare se un oggetto ha un dato
tipo con l’operatore “instanceof”
 if (myObject instanceof Comparable) …
Programmazione ad Oggetti
35
© M. Badella G. Malnati L. Tessitore, 2003-05
Interfacce vuote
Alcune interfacce non hanno metodi
 Servono solo come “marcatori” o indicatori di
tipo
 Indicano che gli oggetti delle classi che le
implementano godono di qualche proprietà
Programmazione ad Oggetti
36
© M. Badella G. Malnati L. Tessitore, 2003-05
Interfacce vuote
public interface Clonable {
//indica che è lecito usare,
// sulle istanze di questa classe
// il metodo Object.clone()
}
public class Rettangolo extends Forma
implements Comparable , Clonable {
public int compareTo(Object o) {
//codice relativo…
}
//altri attributi e metodi…
}
Programmazione ad Oggetti
37
Scarica

slide della lezione - ppt