Ereditarietà - uniroma1.itbloisi/didattica/pmn1112/... · Ereditarietà L’ereditarietà nei...
Transcript of Ereditarietà - uniroma1.itbloisi/didattica/pmn1112/... · Ereditarietà L’ereditarietà nei...
Corso di Programmazione e Metodi NumericiIngegneria Aerospaziale – BAER
Unità 9
Ereditarietà
Unità 9
Domenico Daniele Bloisi
Docenti
Metodi Numericiprof. Vittoria [email protected]
Programmazioneprof. Domenico Daniele [email protected]@dis.uniroma1.it
Sito del corso http://www.dis.uniroma1.it/~pmn
Nota: %7E corrisponde alla tilde ~
Pagina 22011/2012EreditarietàUnità 9
Orario delle Lezioni
Lunedì 10.15 – 11.45Martedì 08.30 – 10.00Martedì 08.30 – 10.00Giovedì 10.15 – 11.45Venerdì 10.15 – 11.45
Aula 15, Via Scarpa 14Aula 15, Via Scarpa 14
Pagina 32011/2012EreditarietàUnità 9
Informazioni Generali
Ing. Domenico Daniele Bloisi, PhD
Dipartimento di Ingegneria Informatica Automatica e GestionaleAutomatica e GestionaleVia Ariosto 25(adiacente Piazza Dante,
A fermate Manzoni, Vittorio Emanuele,Tram 3 fermata via Labicana)
mailto:[email protected]
http://www.dis.uniroma1.it/~bloisiPagina 42011/2012Ereditarietà
Unità 9
Sommario – Unità 9
• Modularizzazione e astrazione• Definizione di classi• Metodi e variabili di istanza• Metodi e variabili di istanza• Controllo di accesso• Creazione dinamica di oggetti• Ridefinizione degli operatori• Progettazione di classi• Ereditarietà• Ereditarietà• Overriding dei metodi e polimorfismo
Pagina 52011/2012EreditarietàUnità 9
Creazione dinamica di un'istanzadella classeCome nel caso dei tipi di dati predefiniti, anche p er le istanze di una classe si può utilizzare il meccanismo di creazione dinamica.creazione dinamica.
Questo non comporta alcuna differenza per quanto riguarda la definizione della classe, ma soltanto pe r il programma cliente.
Pagina 62011/2012EreditarietàUnità 9
Esempi
Persona *p = new Persona("Antonio","roma",30);cout << "nome: " << p->getNome() << endl;p- >setResidenza (" milano ");p- >setResidenza (" milano ");cout << "eta\': " << p->getEta() << endl;delete(p);
L’istanza della classe persona viene creata usando l’allocazione dinamica tramite l’operatore new.
Pagina 72011/2012EreditarietàUnità 9
l’allocazione dinamica tramite l’operatore new.L’oggetto dovrà essere esplicitamente rilasciato tr amitel’operatore delete .La definizione della classe non varia.
Accessibilità degli oggetti
Persona *p1 = new Persona("Antonio","roma",30);Persona *p2 = new Persona("Paolo","roma",31);p1 = p2 ;p1 = p2 ;
L’istruzione di assegnazione imposta il riferimento di p1 uguale a quello di p2
Pagina 82011/2012EreditarietàUnità 9
L’area di memoria dell’oggetto associato ad “Antonio” rimarrà allocata, ma non disponibile , per tutta l’esecuzione del programma.
Accessibilità degli oggetti
Persona p1("Antonio","roma",30);Persona p2("Paolo","roma",31);p1 = p2 ;p1 = p2 ;
Nel caso di allocazione statica, come nell’esempio sopra, l’operatore di assegnazione tra oggetti della classe (e non tra riferimenti) ha
Pagina 92011/2012EreditarietàUnità 9
tra oggetti della classe (e non tra riferimenti) ha un significato diverso , cioè di copia della memoria
Ridefinizione di operatori
In C++ è possibile ridefinire gli operatori dellinguaggio=,==,+,<,>,<<,>>=,==,+,<,>,<<,>>per specializzarli agli oggetti delle classi defini te dall'utente.
Per esempio, l’operatore == ha un significato particolare per gli oggetti della classe string .
Pagina 102011/2012EreditarietàUnità 9
particolare per gli oggetti della classe string .
Uguaglianza tra oggetti
Definizione dell’operatore == per confrontare due persone
Nel file Persona.h si aggiunge la dichiarazione Nel file Persona.h si aggiunge la dichiarazione dell’operatore nella dichiarazione della classe.
class Persona {...bool operator==(const Persona& B) const;
};
Pagina 112011/2012EreditarietàUnità 9
};
Uguaglianza tra oggetti
Definizione dell’operatore == per confrontare due persone
Nel file Persona.cpp si implementa l’operatore come Nel file Persona.cpp si implementa l’operatore come segue.
bool Persona::operator==(const Persona& B) const {return (nome == B.nome) &&
(residenza == B.residenza) &&(eta == B.eta);
}
Pagina 122011/2012EreditarietàUnità 9
}
Esempio
Persona p1("Luigi", "roma", 30);Persona p2("Luigi", "roma", 30);if ( p1 == p2 )if ( p1 == p2 )
cout << "Sono uguali" << endl;else
cout << "Sono diversi" << endl;
stampa Sono uguali.
Pagina 132011/2012EreditarietàUnità 9
stampa Sono uguali.
Copia di oggetti
Per effettuare la copia di un oggetto si può ridefi nire l’operatore di assegnazione =.
Nel file Persona.h si aggiunge la dichiarazione dell’operatore nella dichiarazione della classe.
class Persona {...const Persona & operator=(const Persona& B);
};
Pagina 142011/2012EreditarietàUnità 9
};
Copia di oggetti
Per effettuare la copia di un oggetto si può ridefi nire l’operatore di assegnazione =.
Nel file Persona.cpp si implementa l’operatore come segue.
const Persona& Persona::operator=(const Persona& B) {
nome = B.nome;
Pagina 152011/2012EreditarietàUnità 9
residenza = B.residenza;eta = B.eta;return B;
}
Esempio
Persona p1("Luigi","roma", 30);Persona p2 = p1;if ( p1 == p2 && &p1 != & p2)if ( p1 == p2 && &p1 != & p2)
cout << "Oggetti distinti, " << "contenuto uguale" << endl;
elsecout << "Errore!!!" << endl;
Pagina 162011/2012EreditarietàUnità 9
Ridefinizione di altri operatori
Definizione dell’operatore di flusso di output per l a classe Persona
Nel file Persona.h si aggiunge la dichiarazione dell’operatore nella dichiarazione della classe.
class Persona {...friend ostream &operator<<(ostream &o, Persona &p);
};
Pagina 172011/2012EreditarietàUnità 9
};
Ridefinizione di altri operatori
Definizione dell’operatore di flusso di output per l a classe Persona
Nel file Persona.cpp si implementa l’operatore come segue.
ostream& operator<<(ostream &o, Persona &p) {o << "[" << p.nome << ", " << p.residenza <<
", " << p.eta << "]";return o;
Pagina 182011/2012EreditarietàUnità 9
return o;}
Note
La parola chiave friend permette a classi o funzioni che non sono membri di una determinata classe l'accesso a dati privati di quella classe .l'accesso a dati privati di quella classe .
L’operatore << è in effetti una funzione globale ( non membro della classe ), ma è dichiarata all’interno della classe e con il modificatore friend , in modo da consentire l’accesso anche ai campi privati, che altrimenti non sarebbe possibile .
Pagina 192011/2012EreditarietàUnità 9
altrimenti non sarebbe possibile .
Note
L’operatore << effettua le operazioni su un flusso di output di tipo ostream , che può essere lo schermo (cout ) o un file (oggetto ofstream ) e restituisce lo (cout ) o un file (oggetto ofstream ) e restituisce lo stesso stream per effettuare successive operazioni di scrittura sullo stream .In questo modo si possono concatenare flussi di div erso tipo.
Pagina 202011/2012EreditarietàUnità 9
Esempio
Persona p1("Nicola"," roma",30);Persona p2 ("Sara"," milano ",20);cout << "p1 = " << p1 << endl ;cout << "p1 = " << p1 << endl ;cout << "p2 = " << p2 << endl ;
stampa
p1 = [Nicola, roma, 30]
Pagina 212011/2012EreditarietàUnità 9
p1 = [Nicola, roma, 30]p2 = [Sara, milano , 20]
Altri aspetti della definizione delleclassi
• parametro implicito this
• variabili e metodi statici
Pagina 222011/2012EreditarietàUnità 9
Il parametro this
I metodi hanno tutti un parametro formale implicito standard denotato da this .
Questo parametro denota l’oggetto di invocazione.A fronte di una invocazione del metodo, this viene legato al riferimento dell’oggetto di invocazione ch e quindi funge da parametro attuale.
Il parametro this viene usato per accedere a variabili
Pagina 232011/2012EreditarietàUnità 9
Il parametro this viene usato per accedere a variabili di istanza e ai metodi dell’oggetto di invocazione.
Nota
Si noti che in generale this può essere omesso: il linguaggio lo inserisce omesso: il linguaggio lo inserisce automaticamente ogni volta che utilizziamo una variabile di istanza o un metodo della classe.
Pagina 242011/2012EreditarietàUnità 9
Uso di this
In alcuni casi, l'uso di this rende più leggibile ilprogramma, mentre il suo uso è necessario in casodi omonimia delle variabili di istanza e delle variabil idi omonimia delle variabili di istanza e delle variabil io dei parametri formali dichiarati nel metodo, comemostrato nell'esempio seguente.
Persona::Persona(string const &nome,string const &residenza,int eta)
{
Pagina 252011/2012EreditarietàUnità 9
{this->nome = nome;this->residenza = residenza;this->eta = eta;
}
Variabili e metodi statici
Le variabili statiche sono zone di memoria condiviseda tutti gli oggetti della classe.
I metodi statici sono metodi definiti all'interno d ellaclasse che sono invocati indipendentemente daglioggetti delle classi e che non possono accedere all evariabili di istanza (in quanto non associati ad alc unoggetto), ma solo alle variabili statiche.
Pagina 262011/2012EreditarietàUnità 9
Definizione e accesso di campi statici
Le definizione di campi (variabili e metodi) static i di una classe si effettua anteponendo la parola di una classe si effettua anteponendo la parola chiave static alla definizione del campo .
L'accesso ai campi statici e effettuato con la sintassinomeClasse :: nomeCampo
Pagina 272011/2012EreditarietàUnità 9
Ereditarietà
L’ereditarietà nei linguaggi orientati agli oggetti consiste nella definizione di una classe che è una specializzazione di una classe già esistente : una specializzazione di una classe già esistente : cioè di una classe che ha le stesse caratteristiche di una classe già esistente, ma alla quale si vogliono aggiungere delle nuove funzionalità (comportamenti) e/o nuove informazioni.
Pagina 282011/2012EreditarietàUnità 9
informazioni.
Ereditarietà
Invece di modificare la classe già definita, si cre a una nuova classe derivata da essa.
class Studente : public Persona {...
};
• Studente è una sottoclasse di Persona .Persona è una superclasse di Studente .
Pagina 292011/2012EreditarietàUnità 9
Persona è una superclasse di Studente .
• Studente è una classe derivata dalla classe basePersona .
Ereditarietà
Una sottoclasse eredita tutti i metodi e le variabili di istanza della superclasse e, invariabili di istanza della superclasse e, inpiù, può avere dei metodi e variabili di istanza specifici.
Pagina 302011/2012EreditarietàUnità 9
Esempio
class Studente : public Persona {private:
string facolta;public:public:
Studente(string n, string r, int e, string f);string getFacolta();
};
Gli oggetti della classe Studente sono caratterizzati
Pagina 312011/2012EreditarietàUnità 9
Gli oggetti della classe Studente sono caratterizzati dalle proprietà ereditate dalla classe Persona e, in aggiunta, dalla facoltà a cui lo studente è iscritt o.
Caratteristiche fondamentali delleclassi derivate• Tutte le proprietà (variabili di istanza e metodi) definite per la classe base vengono implicitamente definite anche nella classe derivata, cioè vengono ereditate danella classe derivata, cioè vengono ereditate daquest’ultima.
• La classe derivata può avere ulteriori proprietà r ispetto a quelle ereditate dalla classe base.
• Ogni oggetto della classe derivata è anche un oggetto
Pagina 322011/2012EreditarietàUnità 9
• Ogni oggetto della classe derivata è anche un oggetto della classe base e ciò implica che è possibile usa re un oggetto della classe derivata in ogni situazione ocontesto in cui si può usare un oggetto della class e base.
Costruttore di una classe derivata
Studente::Studente(string n, string r, int e, string f): Persona(n,r,e) // invoca il costruttore di Persona{{
facolta = f;}
Pagina 332011/2012EreditarietàUnità 9
Metodi e variabili ereditati
Gli oggetti della classe Studente ereditano tutti imetodi e le variabili di istanza di Persona
int main() {Persona *p = new Persona("Mario", "Roma", 50);cout << p->getNome() << p->getResidenza() << endl;Studente *s =
new Studente("Anna", "Roma", 23, "Lettere");cout << s->getNome() << s->getResidenza() <<
s- >getFacolta () << endl ;
Pagina 342011/2012EreditarietàUnità 9
s- >getFacolta () << endl ;}
Compatibilità
Oggetti delle classi derivate sono compatibili con glioggetti delle classi base (non il viceversa).
int main() {Persona *p = new Persona("Mario", "Roma", 50);Studente *s = new Studente("Anna", "Roma", 23,
"Ingegneria");Persona *pp;Studente *ss;pp = s; //OK! Studente è compatibile con Personass = p; //ERRORE! Persona non è compatibile con Studentecout << pp- >getNome (); // OK
Pagina 352011/2012EreditarietàUnità 9
cout << pp- >getNome (); // OKcout << pp->getResidenza(); // OKcout << pp->getFacolta(); // ERRORE! getFacolta non è un
// metodo di Persona}
Compatibilità tra parametri attuali eformali
Quanto visto a proposito delle regole di compatibil ità tra superclasse e sottoclasse si applica anche al passa ggio dei parametridei parametri
void stampaPersona(Persona* p) {cout << p->getNome() << p->getResidenza() <<
endl;}
void stampaStudente ( Studente* s) {
Pagina 362011/2012EreditarietàUnità 9
void stampaStudente ( Studente* s) {cout << s->getNome() << s->getResidenza() <<
s->getFacolta() << endl;}
Compatibilità tra parametri attuali eformaliint main() {
Persona *p =new Persona("Mario", "Roma", 50);new Persona("Mario", "Roma", 50);
Studente *s = new Studente("Anna", "Roma", 23, "Ingegneria");
stampaPersona(p);stampaPersona(s);stampaStudente(p);stampaStudente (s );
Pagina 372011/2012EreditarietàUnità 9
stampaStudente (s );}
stampaStudente(p); è errata in quanto p non è compatibile con Studente .
Overriding di metodi
Si dice che si e fatto overriding (letteralmente"sovrapposizione") di un metodo m() quandonella sottoclasse di definisce un metodo m()nella sottoclasse di definisce un metodo m()avente esattamente la stessa segnatura delmetodo m() della superclasse.
Pagina 382011/2012EreditarietàUnità 9
Overriding: esempio
class Persona {...void stampa();void stampa();virtual void stampav();
};void Persona::stampa() {
cout << nome << " " << residenza << " " << eta << endl;
}
Pagina 392011/2012EreditarietàUnità 9
void Persona::stampav() {cout << nome << " " << residenza << " "
<< eta << endl;}
Overriding del metodo stampa
class Studente : public Persona {...void stampa();void stampa();virtual void stampav();
};
void Studente::stampa() {cout << getNome() << " " << getResidenza() <<
" " << getEta() << " " << facolta << endl;}
Pagina 402011/2012EreditarietàUnità 9
void Studente::stampav() {cout << getNome() << " " << getResidenza() <<
" " << getEta() << " " << facolta << endl;}
Funzioni virtual
Quando una classe derivata eredita da una classe ba se, un oggetto della classe derivata può essere considerato sia come appartenente alla classe base sia considerato sia come appartenente alla classe base sia come appartenente alla classe derivata.
Se c’è overriding di un metodo, la chiamata risulta ambigua.
Se una funzione viene definita virtual nella classe
Pagina 412011/2012EreditarietàUnità 9
Se una funzione viene definita virtual nella classe base, allora la funzione della classe derivata sarà chiamata (se esiste). Se non è definita virtual , sarà invocata la funzione della classe base.
Esempio di cliente
int main() {Persona *p =
new Persona("Mario", "Roma", 50);new Persona("Mario", "Roma", 50);Studente *s = new Studente("Anna",
"Roma", 23, "Ingegneria");p->stampa();s->stampa();p->stampav();s- >stampav ();
Pagina 422011/2012EreditarietàUnità 9
s- >stampav ();}
Output
Mario Roma 50Anna Roma 23 IngegneriaMario Roma 50Mario Roma 50Anna Roma 23 Ingegneria
Pagina 432011/2012EreditarietàUnità 9
Polimorfismo
L’overriding di metodi porta ad avere polimorfismo, ovvero la presenza di metodi polimorfismo, ovvero la presenza di metodi con la stessa segnatura che si comportano in modo diverso all’interno di una gerarchia diclassi.
Pagina 442011/2012EreditarietàUnità 9
Esempio
int main() {Persona *p = new Persona("Mario", "Roma", 50);Studente *s = new Studente("Anna", "Roma", 23, Studente *s = new Studente("Anna", "Roma", 23,
"Ingegneria");Persona *ps = s; // OK per le regole di
//compatibilitàp->stampa();s->stampa();ps->stampa(); // ??? cosa stampa ???ps->stampav(); // ??? cosa stampa ???
}
Pagina 452011/2012EreditarietàUnità 9
}
Output
Mario Roma 50Anna Roma 23 IngegneriaAnna Roma 23Anna Roma 23Anna Roma 23 Ingegneria
Pagina 462011/2012EreditarietàUnità 9
Gerarchia di classi
• Una classe può avere molte sottoclassi.Per esempio, è possibile definire una sottoclassePersonaEsperta di Persona i cui oggetti rappresentano PersonaEsperta di Persona i cui oggetti rappresentano persone esperte in una data materia, dove la materi a di cui sono esperti è una proprietà specifica della cl asse.
• Una sottoclasse di una classe può avere a sua volt a sottoclassi. Per esempio, la classe Studente derivata da Persona può avere una sottoclasse StudenteLavoratore .
Pagina 472011/2012EreditarietàUnità 9
• É possibile quindi creare delle gerarchie di classi attraverso varie derivazioni.