Programmazione Orientata agli Oggetti Lezione 13 La programmazione ad oggetti si basa su due principi fondamentali ereditarietà polimorfismo Queste due proprietà consentono di definire nuovi tipi di dato in funzione di tipi già esistenti si specifica soltanto le parti in cui la nuova classe differisce da quelle note (programmazione per differenze) consente di riciclare tutto il codice presente nelle librerie 1 2001/02 1
Esempio Supponiamo di aver creato una classe per rappresentare i vettori class vettore<t>; È possibile derivare dalla classe precedente una nuova classe che gestisce i vettori ordinati. Non dobbiamo modificare la rappresentazione interna Non dobbiamo modificare tutti i metodi anzi li utilizziamo quasi tutti Dobbiamo modificare solo alcuni metodi/operatori tipo: push_back(); operator[]; 2 Ereditarietà Il meccanismo dell ereditarietà permette di definire una classe in termini di una classe definita in precedenza la nuova classe eredita la rappresentazione in memoria e l interfaccia della sua classe base il programmatore non deve riscrivere tutto il codice che è in comune tra la classe base e la nuova classe il programmatore può modificare l implementazione di alcuni dei metodi ereditati, può aggiungere attributi L ereditarietà consente di implementare relazioni di specializzazione (isa) tra tipi di dato 3 2001/02 2
Relazioni di Specializzazione Consideriamo la classe Video definita nelle precedenti lezioni class Video stringa di char di dimensione altezza*larghezza class Window è un tipo particolare di Video dimensioni variabili posizione relativa rispetto al video class Menu è un tipo particolare di Window visualizzazione a comparsa selezione tramite mouse 4 Esempio: Sistema Informativo Zoo Estinzione Erbivoro AnimaleZoo Uccello Orso Pesce Felino Panda OrsoBianco Grizzly Yoghi 5 2001/02 3
Derivazione di Classi Il meccanismo della derivazione di classi implementa l operazione di ereditarietà della programmazione ad oggetti La classe derivata può utilizzare tutti i dati ed i metodi non privati della classe base come propri elementi non c è bisogno di riscrivere i metodi ereditati dalla classe base, a meno che non debbano essere modificati Il livello di accesso di un membro della classe può essere privato, pubblico e protetto I membri protetti non sono visibili dall esterno della classe ma sono ereditabili 6 Polimorfismo Il polimorfismo consente di programmare senza tener conto dei dettagli relativi all implementazione di una gerarchia di classi L utente opera sull interfaccia pubblica della classe base Un oggetto di qualunque classe della gerarchia contiene l interfaccia della classe base L implementazione dei metodi può essere differente Quando il programma invoca un metodo della classe base attraverso un oggetto Viene eseguita l implementazione del metodo contenuta nella classe a cui appartiene l oggetto 7 2001/02 4
Esempio di polimorfismo stampa(animalezoo *pa) { pa disegna(); } 8 Progettazione di un sistema per la gestione di poligoni Vogliamo implementare una gerarchia di classi per la gestione di poligoni Bisogna decidere Quali sono gli attributi della classe base e quali aggiungere nelle classi derivate Quali metodi ridefinire nelle classi derivare, quali in quella base 9 2001/02 5
La gerarchia di classi figura poligono cerchio quadrato rombo rettangolo 10 Sistema per la gestione di poligoni 1 Ci saranno attributi per Numero lati, lati Numero vertici, vertici Colore bordo, colore sfondo // Non li utilizzeremo Non ci preoccuperemo di verificare se una serie di lati rappresenta un poligono 11 2001/02 6
Sistema per la gestione di poligoni 2 Ci saranno dei metodi per Calcolare l area del poligono Calcolare il perimetro del poligono Metodi di accesso // Non li implementeremo Leggi/Setta numero lati Leggi/Setta valore per ogni lato Stampa del poligono // Non verrà implementato 12 Interfaccia Pubblica di Poligono class Poligono { public: Poligono(); Poligono(int N, const vector<double>&); // Crea un poligono con N lati con // grandezze memorizzate nel vettore Poligono(const vector<punti>&); double area(); double perimentro(); void setta_sfondo(colore); // Non implementato void setta_bordo(colore) // Non implementato void disegna(); // Non implementato }; 13 2001/02 7
Rappresentazione Poligono class Poligono { protected: int _NumLati; vector<double> _Lati; color _Sfondo; // color potrebbe essere un enum color _Bordo; }; 14 Uso della classe Poligono #include Poligono.h" int main() { } vector<double> quadrato(4,0); quadrato[0]=quadrato[1]=quadrato[2]=quadrato[3]=4; Poligono p(4,quadrato); cout << p.area() << endl; cout << p.perimetro() << endl; 15 2001/02 8
Proprietà della classe Poligono Il metodo per il calcolo del perimetro è uguale per ciascun tipo di poligono Il metodo per il calcolo dell area è diverso per ciascun tipo di poligono Il programma deve ignorare queste differenze e operare su un unico metodo 16 Classe Poligono La classe Poligono identifica il concetto astratto di poligono Ogni figura geometrica ha una funzione per il calcolo dell area Ogni figura geometrica, di qualunque tipo, può essere convertita in un oggetto poligono 17 2001/02 9
Classe Poligono Se il metodo disegna() è polimorfico è possibile scrivere un programma del genere (disegna() è definito come funzione virtuale di Poligono) void stampa(const Poligono* pq) { pq->disegna(); } int main() { Quadrato q; Rettangolo rt; Rombo rm; stampa(&q); stampa(&rt); stampa(&rm); } 18 Progettazione di una Gerarchia di Classi Il paradigma dell object oriented è basato sui concetti di fornitore e utente Il fornitore progetta ed implementa la classe base Altri fornitori progettano ed implementano classi derivate L utente usa l interfaccia pubblica della gerarchia L utente dovrebbe essere messo in condizione di ignorare la struttura della gerarchia Deve conoscere solo l interfaccia pubblica della classe base Gli altri sviluppatori dovrebbero essere messi in grado di poter sviluppare classi derivate trasparenti all utente 19 2001/02 10
Progettazione di una Gerarchia di Classi Nel progettare una classe si deve rispondere ai seguenti quesiti Quali operazioni deve fornire l interfaccia pubblica dell intera gerarchia? Quali di queste operazioni hanno implementazioni diverse per ciascuna classe derivata? Quali membri dato sono comuni a tutta la gerarchia? Quali membri dato devono essere visibili per poter costruire classi derivate? 20 2001/02 11