UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Progettazione e Programmazione Orientata agli Oggetti Giovanni Rimassa DII - Università di Parma G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Programmazione ad Oggetti • La programmazione ad oggetti (OOP) è una parte importante delle moderne tecniche di sviluppo del software. • Le tecnologie OO permeano tutto il ciclo di sviluppo del software – OOA - (Object Oriented Analysis) – OOD - (Object Oriented Design) – OOP - (Object Oriented Programming) G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Programmazione ad Oggetti • Negli ultimi 15 anni, le tecnologie OO hanno preso sempre più piede. • Oggi gli oggetti sono talmente mainstream che nessuno li contesta più apertamente. • Tuttavia, la comprensione dei principi linguistici e di progetto alla base della OOP non è così diffusa come sembra. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Programmazione ad Oggetti • Le soluzioni proposte dalla OOP nascono da considerazioni generali di Ingegneria del Software. • Le tecnologie orientate agli oggetti cercano di favorire la progettazione di software di qualità. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING La Qualità del Software • Un sistema software può essere valutato in base a molte qualità, che si possono dividere in due grandi categorie: • Qualità Esterne (viste dal cliente/utente) – Correttezza, Efficienza, Usabilità, ... • Qualità Interne (viste dallo sviluppatore) – Mantenibilità, Estendibilità, ... G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Modularità • La modularità viene spesso considerata una qualità interna, ma in realtà non è chiaramente definita. • Si potrebbe definire informalmente così: – Un sistema è modulare se i suoi moduli sono “ben strutturati” e “ben collegati insieme”. ⇒ Cerchiamo delle proprietà più precise. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Modularità • Per descrivere la modularità e mostrare come essa supporti le qualità interne del software, vedremo: – Cinque Criteri (per valutarla) – Cinque Regole (per garantirla) – Cinque Principi (per praticarla) G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Criteri (1) • Decomponibilità – Un sistema modulare può essere decomposto in parti più piccole, connesse da una struttura semplice, abbastanza indipendenti da lavorarci separatamente. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Criteri (2) • Componibilità – Un sistema modulare favorisce la produzione di elementi che possono essere combinati insieme in un ambiente diverso da quello in cui sono stati creati. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Criteri (3) • Comprensibilità – In un sistema modulare ogni parte può essere compresa isolatamente da un osservatore umano, senza che questo debba conoscere le altre parti. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Criteri (4) • Continuità – Un sistema modulare è tale che ad un cambiamento “piccolo” nelle specifiche del sistema corrisponda un cambiamento “piccolo” nell’implementazione. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Criteri (5) • Protezione – Un sistema modulare confina gli effetti di condizioni anormali all’interno del modulo in cui avvengono, o al più in un numero ristretto di moduli. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Regole(1) • Corrispondenza Diretta – La struttura modulare del sistema software dovrebbe rimanere compatibile con quella del problema che il sistema tenta di risolvere. • Una qualità molto citata dell’approccio OO è che si riesce a modellare il software sulla base del “mondo reale” – Ma “compatibile” non vuol dire “speculare” G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Regole(2) • Poche Interfacce – Ogni modulo dovrebbe comunicare con il minor numero possibile di altri moduli. • Questa regola serve a supportare la continuità e la protezione. – Se un modulo ha poche interfacce, i suoi cambiamenti si rifletteranno su pochi altri. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Regole(3) • Interfacce Piccole – Quando due moduli comunicano, dovrebbero scambiarsi meno informazioni possibile. • Anche questa regola supporta la continuità e la protezione. – Se un modulo ha interfacce piccole, i suoi cambiamenti si rifletteranno poco sui suoi (pochi) vicini. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Regole(4) • Interfacce Esplicite – Il fatto che due moduli comunicano dovrebbe essere ovvio leggendo il loro codice. • Questa regola supporta comprensibilità, componibilità, decomponibilità e continuità. – Le interfacce esplicite aiutano a capire il modulo ed a prevedere gli effetti dei cambiamenti, ad anche a comporlo/scomporlo. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Regole(5) • Information Hiding – un modulo deve dichiarare un sottoinsieme pubblico delle sue informazioni. • Questa regola è il cardine fondamentale per ottenere la continuità. – Ogni decisione di progetto o implementazione che non viene rivelata agli altri moduli può essere rivista senza influenzarli. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi • I criteri e le regole visti prima esprimono (apparentemente) concetti legati più al progetto del sistema che al linguaggio di programmazione. • I cinque principi seguenti, invece, si riflettono sui costrutti linguistici e sono il riflesso pratico delle regole viste prima. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi (1) • Unità Linguistiche Modulari – Il linguaggio di programmazione deve supportare i moduli come unità sintattiche. • I criteri di modularità devono arrivare fino all’implementazione: se il linguaggio non sa esprimere in forma compilabile i moduli individuati nelle fasi precedenti, non si può costruire un sistema modulare. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi (2) • Documentazione Incorporata – La documentazione interna di un modulo deve essere contenuta nel modulo stesso. • Una buona documentazione incrementa la comprensibilità, ma deve essere aggiornata o diventa addirittura fuorviante e dannosa. – Mantenere la documentazione vicino al codice. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi (3) • Accesso Uniforme – I servizi esposti da un modulo non devono rivelare se sono implementati con calcoli o con dati. • Questo principio serve a rispettare l’information hiding ed aiuta a garantire la continuità; consente al modulo di cambiare i trade-off spazio-tempo senza problemi. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi (4) • Aperto/Chiuso (Open/Closed Principle) – Il linguaggio di programmazione deve permettere di creare moduli aperti per l’estensione, ma chiusi per l’utilizzo. • Chi usa un modulo vuole saperne il meno possibile (black box). • Per essere esteso, un modulo deve rivelare qualcosa in più (white box). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Cinque Principi (5) • Scelta Singola (Single Choice Principle) – Ogni volta che ci sono un certo numero di alternative, al più un modulo deve conoscerne l’elenco. • Quando “i casi sono due” nella versione 1.0, si può star sicuri che “i casi sono quindici” nella versione 2.0. – Per salvaguardare continuità ed estendibilità. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Tipi di Dato • Al livello più basso, programmi e dati non sono altro che sequenze di byte. – Un virus infetta tutti i programmi nello stesso modo. – Le tecniche di protezione e cracking sono indipendenti dal tipo di programma. – MAME o VMWare fanno girare applicazioni sconosciute ai progettisti dell’emulatore. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Tipi di Dato • Curiosamente, anche alcuni linguaggi di livello molto alto rappresentano dati e programmi in modo omogeneo. – In LISP si esprime tutto come cella o lista. – Molti linguaggi di scripting hanno un solo tipo di dato. – Una Macchina di Turing ne può simulare un’altra. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Tipi di Dato • “Si è tanto ciechi nell’oscurità totale quanto nella luce totale”. • Modelli troppo omogenei riducono la comprensibilità e la decomponibilità. – Linguaggi strettamente tipati. – Typing statico e typing dinamico. – Tipi come categorie per la modellazione. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Tipi di Dato • Insegnando un linguaggio, si devono introdurre i tipi di dato supportati. • A livello elementare, si introducono i tipi attraverso una loro rappresentazione. – Gli array bidimensionali in C sono memorizzati per righe. – Una struct in C è fatta dalla sequenza dei suoi campi. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Tipi di Dato • Per ottenere alcune qualità interne quali decomponibilità e protezione, non ci si deve basare sulla rappresentazione di un tipo, ma: – Sulle operazioni ad esso applicabili. – Sulle proprietà garantite per ogni istanza del tipo. – Sulle precondizioni di ogni operazione. ⇒ Si parla di Abstract Data Type. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING ADT: Un Esempio • Type: STACK<REAL> • Functions – push: (STACK<REAL>, REAL)→ STACK<REAL> – … (pop, top, remove) • Axioms – top(push(s, x)) = x – … • Preconditions – pop require not empty – … G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Moduli e Tipi • Moduli e tipi sembrano molto diversi. – I moduli strutturano l’implementazione. – I tipi specificano come usare ogni parte. • Ma in comune c’è il concetto di interfaccia. – Nei moduli determina la parte pubblica. – Nei tipi descrive le operazioni ammissibili e le loro proprietà. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione OOP Il concetto fondamentale della programmazione ad oggetti è: L’Oggetto La Classe G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione OOP • Def: Classe – “Un tipo di dato astratto corredato da un modulo che ne è un’implementazione.” Tipo + Modulo = Classe G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Classi Point - double x - double y - numOfPoints + Point(double x, double y) + void move(double dx, double dy) + int howMany() • Una classe Point, espressa nella notazione standard UML (Unified Modeling Language). – – – – Dati privati. Funzioni pubbliche. Membri di istanza. Membri di classe. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Classi in C++ ed in Java // File Point.H class Point { // C++ public: Point(double x, double y); void move(double dx, double dy); static int howMany(); private: double m_x; double m_y; static int numOfPoints; }; // Implementazione in Point.cc // File Point.java class Point { // Java public Point(double x,double y) {…} public void move(double dx, double dy) {…} public static int howMany() {…} private double myX; private double myY; private static int numOfPoints; } // Implementazione in linea G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Oggetti • Un oggetto in notazione UML. aPoint:Point x:double = 1.3 y:double = -5.8 – Un oggetto è un’istanza di una classe (che è il suo tipo ed il modulo che ne regola l’accesso). – Un oggetto ha struttura ed operazioni della sua classe, ma specifici valori per gli attributi. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Oggetti • Oggetti della stessa classe hanno operazioni uguali (metodi), ma dati diversi. • Un metodo può accedere ai dati dell’oggetto (parte privata del modulo). • Come si indica al metodo su quale oggetto agire ? – Istanza corrente di un oggetto (this o self). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Chiamata a Metodo Meccanismo fondamentale di computazione della OOP Risultato res = obj.meth(par) Oggetto Target Operatore di accesso G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti Lista di parametri Nome del metodo COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Oggetti in C++ e Java // File main.cc - C++ #include “Point.H” // File Main.java - Java import Point; void main(int argc, char *argv[]) { Point p(1,2); // Oggetto locale Point* pptr; // Puntatore class Main { public static void main(String[] args) { pptr = new Point(0,0); // Alloca p.move(-4,7); // Method call pptr->move(3,-6); // Method call Point p; // Riferimento nullo p = new Point(0,0); // Alloca p.move(-5,-9); // Method call delete pptr; pptr = 0; } // p distrutto automaticamente p = null; // Garbage collection } } G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Oggetti in C++ e Java // File point.cc - C++ #include “Point.H” // File Point.java class Point { // Java // Implementazione separata void Point::move(double dx, double dy) { // Implementazione in linea public void move(double dx, double dy) { // this - all’interno di un // metodo e` il puntatore // all’istanza corrente this->m_x = this->m_x + dx; // this - all’interno di un // metodo e` il riferimento // all’istanza corrente this.myX = this.myX + dx; // ‘this’ si puo` omettere m_y = m_y + dy; // ‘this’ si puo` omettere myY = myY + dy } } G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ciclo di Vita degli Oggetti • Ogni classe impone dei vincoli su tutti i suoi oggetti. – Precondizioni all’ingresso dei metodi. – Postcondizioni all’uscita dei metodi. – Invarianti che devono sempre valere. • Gli oggetti devono gestire risorse durante la loro esistenza (memoria, file, entità del S.O.). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ciclo di Vita degli Oggetti • Momenti critici della vita di un oggetto: – Creazione. – Copia. – Distruzione. • La creazione è ben più dell’allocazione. • La copia incide sulle chiamate a metodo. • La distruzione deve rimettere tutto a posto. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ciclo di Vita in C++ • In C++ esistono alcuni metodi particolari: – I costruttori, che creano e copiano gli oggetti. – L’operatore di assegnazione, che sostituisce un oggetto con un altro. – Il distruttore, che distrugge gli oggetti. • La gestione della memoria è manuale. – Protocollo Prologo/Epilogo. – Allocazione sullo stack, sullo heap o statica. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ciclo di Vita in Java • In Java, esistono alcuni metodi particolari: – I costruttori, che creano gli oggetti. – Il metodo clone(), che copia gli oggetti. • La gestione della memoria è automatica. – Nella JVM c’è un garbage collector. – Il momento della distruzione non è noto. – Allocazione sullo heap (tutti puntatori). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Ereditarietà Shape Shape Circle Triangle Square Circle Persistent Triangle • Esprime una relazione is-a fra due classi. – Relazione gerarchica ed aciclica. • Può essere singola o multipla. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti Square UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ereditarietà • L’ereditarietà è un meccanismo base della OOP, ma ha più aspetti diversi. • La prima distinzione da fare è tra ereditarietà di interfaccia ed ereditarietà di implementazione. – Tipo – Subtyping + Modulo = Classe. + Inheritance = Subclassing. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Subtyping • Se le classi sono tipi, l’ereditarietà è una relazione tra tipi, che chiamiamo subtyping. • Se il tipo D è un sotto-tipo del tipo B, cosa significa D is-a B ? – Tutto quello che posso fare ad un B lo posso fare anche ad un D. ⇒ Principio di Sostituibilità di Liskov. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Inheritance • L’ereditarietà è una relazione tra moduli, che chiamiamo (solo qui) inheritance. • L’inheritance garantisce l’Open/Closed Principle. – Un sotto-modulo avrà accesso privilegiato al modulo base (accesso protected in C++ e Java). – Un sotto-modulo potrà cambiare o estendere l’implementazione del modulo base. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ereditarietà in C++ • Il C++ supporta completamente l’ereditarietà. – Ereditarietà singola e multipla. – Ereditarietà multipla ripetuta e condivisa. – Ereditarietà pubblica, protetta e privata. • In C++ si può avere: – Subtyping puro (classi puramente astratte). – Inheritance pura (ereditarietà privata). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Ereditarietà in Java • Java supporta quasi completamente l’ereditarietà. – Inheritance singola. – Subtyping multiplo. – Invocazione dei metodi ereditati tramite il riferimento super. • In Java si può avere: – Subtyping puro (interfacce). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo • Il polimorfismo è una caratteristica essenziale dei linguaggi orientati agli oggetti. • Permette di trattare in modo uniforme tipi “simili”, ma rispettandone le differenze. • Spesso il polimorfismo si usa per garantire il Single Choice Principle. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Polimorfismo • Si individuano delle operazioni comuni per interfaccia, ma diverse per comportamento. • Una classe dichiara la funzione e delle sottoclassi ne forniscono diverse implementazioni. Shape + void draw(GC& aCtx) Circle + void draw(GC& aCtx) Triangle + void draw(GC& aCtx) Square + void draw(GC& aCtx) G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo • Per il Principio di Sostituibilità: – Un riferimento di tipo Shape può puntare a oggetti di tipo Shape o di una sottoclasse. • Esiste un tipo statico ed un tipo dinamico: – Tipo statico ⇒ tipo del riferimento, dichiarato a compile time. – Tipo dinamico ⇒ tipo dell’oggetto puntato a run time. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo • Quando tipo statico ≠ tipo dinamico, se le due classi hanno versioni diverse di una stessa funzione membro, sorge un problema di binding. – Static binding (o early binding) ⇒ tipo statico. – Dynamic binding (o late binding) ⇒ tipo dinamico. • Il late binding è possibile solo con ptr/ref. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo • Nell’esempio delle figure geometriche: – La funzione draw(ctx) viene chiamata su un ref di tipo Shape: s.draw(ctx); – Circle::draw(), se s punta ad un Circle. – Square::draw(), se s punta ad uno Square. ⇒ L’oggetto sa il suo vero tipo e la funzione fa la cosa giusta! G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo • Nel caso delle figure geometriche: – Shape::draw(), non è definita (non si sa disegnare una “figura generica”). – Shape ha un’implementazione incompleta. – Shape è una classe astratta. • Alcune funzioni non si devono cambiare. – Se una funzione non è ridefinibile, il late binding non serve. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Polimorfismo e Class Design • Il progettista della classe base deve decidere quali funzioni membro devono essere polimorfe, quali astratte e quali ordinarie. • La decisione va presa attentamente, ponendosi due domande sulla funzione: – “Si potrà ridefinire nelle classi derivate?” – “Si può fornire un’implementazione generica nella classe base?” G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Polimorfismo in C++ e Java Come dichiarare una funzione f() in Java e C++, a seconda di come (e se) si può ridefinire nelle sottoclassi Non Ridefinibile Implementazione di Default Astratta Java final void f() void f() abstract void f() C++ void f() virtual void f() virtual void f() = 0 G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Gestione delle Eccezioni • Le condizioni di errore sono al centro di un dilemma: – Nella maggior parte dei casi non si presentano. – Quando si presentano, possono avere risultati catastrofici. • Serve una soluzione che consenta di trattare gli errori, senza inquinare il codice eseguito nei casi normali. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Gestione delle Eccezioni • Errori e valori di ritorno: – Quando un metodo fallisce, non ha senso chiedergli un valore di ritorno. – L’uso di valori out of band richiede di ridurre il codominio in modo arbitrario. – Il chiamante deve farcire il codice di test condizionali. – Il chiamante può ignorare l’errore. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Gestione delle Eccezioni • Sia C++ che Java forniscono un meccanismo flessibile per gestire le condizioni di errore: La Gestione delle Eccezioni G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Sintassi per le Eccezioni • C++ e Java hanno sintassi molto simile. • Si racchiude il codice da proteggere in un blocco try. • Un’eccezione si lancia con la parola chiave throw. • I gestori delle eccezioni sono introdotti dalla parola chiave catch. G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Eccezioni in C++ Program.cc Library.cc #include “library.h” void f() { X localX; g(); } void main() { try { f(); // Può tirare un’ecc. } catch(Exception& e) { // Gestisce l’eccezione } } void g() { Y localY; h(); } void h() { if(something_wrong()) throw Exception(“Argh”); } G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti COMPUTER ENGINEERING UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione Eccezioni in Java Program.java Library.java import Library; class Library { void f() throws Exception { X localX = new X(); g(); } public class Program { // ... public static void main() { try { f(); // Può tirare un’ecc. } catch(Exception e) { // Gestisce l’eccezione } } void g() throws Exception { Y localY = new Y(); h(); } void h() throws Exception { if(something_wrong()) throw new Exception(“Argh”); } } } G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti UNIVERSITÀ DEGLI STUDI DI PARMA Dipartimento di Ingegneria dell’Informazione COMPUTER ENGINEERING Eccezioni in C++ e Java • Java obbliga ogni metodo a dichiarare le eccezioni tirate (opzionale in C++). • In C++ gli oggetti locali vengono distrutti mentre l’eccezione si propaga. • Java ha la parola chiave finally per eseguire codice comune ai casi normali ed eccezionali (il C++ sfrutta i distruttori). G. Rimassa - Progettazione e Programmazione Orientata agli Oggetti