03-IntroProgrammazioneAdOggetti
Transcript
03-IntroProgrammazioneAdOggetti
Programmazione ad oggetti: Cenni generali Michelangelo Diligenti Ingegneria Informatica e dell'Informazione [email protected] Argomenti ● Programmazione ad oggetti Motivazioni Classi Metodi e membri Primi cenni di sintassi C++ per realizzare classi Motivazioni per la programmazione ad oggetti ● ● Riusabilità Sviluppo di componenti software indipendenti e portabili Creazione di librerie generiche e facilmente integrabili Estensibilità ● Facile prendere il codice ed estenderlo a nuove funzionalità desiderate Flessibilità Modifiche che siano isolate e non rompano l'intero sistema Facile testare il componete in modo isolato Il processo di progettazione ● Goal: creare un sistema software ● Decomporre il sistema in componenti indipendenti: ● Ripetere in modo iterativo: un componente può essere diviso in sotto-componenti e così via Processo top-down Astrazione Non serve conoscere i dettagli del software ● Per fare design non penso a come implementare! Design può seguire diversi paradigmi Procedurale o Modulare Ad oggetti Astrazione ● ● Definire gli attributi ed i comportamenti delle entità (componenti software), trascurando come queste sono implementate Proprietà Comprensibile nomi sono intiutivi Coerente e corretta fa ciò che si desidera Minima non contiene attributi o comporamenti inutili Completa contiene tutti gli attributi e comportamenti desiderati Forme di astrazione ● Procedurale (funzioni) ● Modulare ● Definisce funzioni che realizzano il task Definisce i parametri passati tra le funzioni Programmazione in C viene spesso fatta con questa modalità Difficile isolare i componenti, non poca riusabilità e flessibilità Difficile capire chi cambia cosa e trovare i bugs Definisce dei moduli con dati e procedure Ogni modulo ha solo una parte visibile dall'esterno (pubblica) Ad oggetti (object-oriented) Tipi di dati astratti implementati da classi Ogni progetto è suddiviso in classi Ogni classe ha definite delle funzionalità pubbliche e private Un oggetto è un'istanza di una classe Programmazione ad oggetti ● Simile al modulare ma con costrutti ben definiti e specifici – ● Costruire un sistema partendo dalle sue parti Ogni parte del sistema è un oggetto con – Attributi o membri o dati: definiscono le sottoparti dell'oggetto. Possono essere ● ● – Altri oggetti Tipi elementari come numeri o stringhe Metodi: definiscono le operazioni che sono effettuabili su un oggetto Programmazione ad oggetti ● ● ● Ogni oggetto può essere riusato in altri contesti Possibile usare l'oggetto per quello che fa, non per come è realizzato Una macchina ci porta dove vogliamo senza sapere esattamente come funziona il suo motore Solo chi implementa conosce i dettagli Astrazione: Non chi fa design o utilizza l'oggetto Implementazione possibile attraverso vari linguaggi – C++, Java, ecc. Processo di astrazione e software Mondo reale Astrazione attributi entità software {data,Dati data,…} Classe funzionalità {method, Metodi method,…} Separazione dell'interfaccia ed implementazione Interfaccia visible nascosta • Interfaccia: Cosa fare Implementazione • Implementazione: Come farlo • Usare l'interfaccia senza sapere nulla dell'implementazione • Programmazione Contract-based • Permette l'astrazione Struttura di una classe ● Classe ● ● ● Astrazione di un oggetto che separa l'interfaccia dall'implementazione Una classe rappresenta tutti i membri di un gruppo di oggetti (istanze della classe) Una classe ha un'interfaccia pubblica ed un' implementazione privata Dati ed algoritmi sono privati e quindi nascosti all'utente Questo evita errate alterazioni dello stato Programmazione ad oggetti: esempio ● Si parte da delle specifiche Specifica: Progetta un catalogo per la musica, che permetta di aggiungere album, informazioni su artisti ed albums, titoli di canzoni e compositori. Gli utenti devono anche essere in grado di cercare informazioni nella collezione. ● ● Spesso importanti dettagli mancano Molto detto non è importante Passo 1: identificare gli oggetti ● Cerchiamo i nomi di cose nelle specifiche musica catalogo utente canzone titolo Progetta un catalogo per la musica, che permetta di aggiungere album, informazioni su artisti ed artista albums, titoli di canzoni e compositori. Gli utenti disco devono anche essere in grado di cercare compositore informazioni nella collezione. informazione ● Specifiche: Cosa considerare come oggetti da convertire in classi? Passo 1: identificare gli oggetti ● ● Un oggetto deve: Essere un entità reale con un chiaro confine Essere rilevante nelle specifiche Attenzione se L'oggetto è un azione L'oggetto astrae due concetti L'oggetto ha nessuna od una sola azione da compiere Passo 1: identificare gli oggetti ● Vediamo i singoli candidati musica: troppo generale e poco concreto catalogo: utile e concreto, si accede dall'esterno utente: entità esterna al sistema, non va modellato ma gli va fornito un modo per fare le sue operazioni sugli oggetti canzone: utile e rilevante titolo: non rilevante, attributo di canzone e disco artista: non rilevante, attributo di disco disco: utile e chiaro, contiene una lista di oggetti canzone compositore: non rilevante, attributo di canzone informazione (troppo generale e non concreto) Passo 2: identificare i dati ● Cosa contiene ogni oggetto? ● Catalogo ● ● Lista di dischi: vector<Disco> Disco Autore: string Titolo: string Lista di canzoni: vector<Canzone> Canzone Compositore: string Titolo: string Passo 3: identificare le funzionalità ● ● ● Catalogo void AggiungiDisco(Disco disco); Disco GetDisco(string titolo); vector<Disco> GetDischi(string autore); Disco vector<Canzone> GetCanzoni(); string GetTitolo(); Canzone string GetCompositore(); string GetTitolo(); Passo 4: stabilire la visibilità ● ● Chi può accedere alle funzionalità di una classe? Chiunque: metodi detti public Solo la classe stessa: metodi detti private Solo alcune classi correlate: metodi detti protected Solo alcuni metodi o classi specifiche: metodi detti friend Metodi public definiscono l'interfaccia di una classe Definiscono come la classe viene usata dall'esterno Riassumendo ● Ogni cosa è modellabile come un oggetto ● Un oggetto ha un tipo: la sua classe ● Un oggetto è associato a: ● Attributi (i dati che definiscono l'oggetto) Funzioni (chiamati metodi in OOP), definiscono tutti ed i soli modi di usarlo Oggetto ha funzioni con cui lo si usa dall'esterno ● Insieme di metodi pubblici formano l'interfaccia Data una classe si costruiscono istanze di essa Come per un float, vi sono infinite possibili istanze di float. Tante sono le istanze di oggetti di una classe. Esempio di classi e visibilità class Point { private: float x; float y; public: float Dist(const }; Dati (attributi) Point& pt); class Rectangle { private: Point anchor; float width, height; public: float Area(); float Perimeter(); Point Center(); }; Metodi (funzionalità) Dati (attributi) Metodi (funzionalità) OOP in C++: primi concetti ● Definizione di classe class NomeClasse { … }; ● Inizio dati o metodi privati private: ● Inizio dati o metodi pubblici public: ● Dato (come qualsiasi dato in C) [float, double, int, AltroNomeClasse…] nomeDato; ● Metodo (simile a funzioni in C) [float, double, int, AltroNomeClasse…] nomeMetodo(Argomenti); OOP in C++: esempio class Serbatoio { private: int livello; public: int Livello() { return livello; } void Riempire(int delta_livello) { livello += delta_livello; } Buona norma avere i dati privati. Permette di evitare che qualcuno modifichi lo stato della classe. Un metodo permette accedere allo stato senza modificarlo void Svuotare(int delta_livello) { livello -= delta_livello; } }; Metodi definiscono come usare la classe OOP in C++: note ● In un metodo di una class C: – tutti i dati di C sono visibili (anche i privati) non necessario passarli – possibile chiamare i metodi pubblici o privati di C stessa class Serbatoio { ● private: Dato privato è visibile int livello; public: void Riempire(int delta_livello) { livello += delta_livello; } void Svuotare(int delta_livello) { Riempire(-delta_livello); } }; Chiamo altro metodo OOP in C++: costruttori class Serbatoio { ... public: Serbatoio() { livello = 0; }; Serbatoio(int livello_iniziale) { livello = livello_iniziale; } }; Esistono dei metodi speciali che hanno il nome della classe. Sono detti Costruttori e definiscono le operazioni da fare per costruire un istanza della classe Vi possono essere più costruttori che prendono diversi parametri. Il costruttore senza parametri è detto Default Constructor Se nessun costruttore è definito, il compilatore ne crea uno di default, ma non sempre fa ciò che si desidera! Buona norma aggiungere i costruttori che si vogliono usare OOP in C++: uso dei metodi #include <iostream> class Serbatoio { ... }; int main() { Serbatoio s(5); s.Riempire(3); usare una classe vuol dire 1) definire un istanza e chiamare il costruttore 2) chiamare l'interfaccia come istanza.metodo() std::cout << s.Livello() << “\n”; return 0; } OOP in C++: istanze di classe #include <iostream> class Serbatoio { ... }; int main() { Serbatoio s1(5); Serbatoio s2(10); Data una class Serbatoio Possibile instanziare un numero infinito di istanze di serbatoi: s1. s2, ... … } ● ● Classe: tipo di oggetto Istanza: variabile che contiene una singola incarnazione di una classe Metodi speciali: accessors ● ● Dati sempre privati Metodi accessors o getters permettono di accedere ai dati privati dall'esterno della classe Sone sempre metodi const, senza parametri Dati restano protetti in quanto non cambiabili Esempio class Serbatoio { Ritorna per const reference private: o per valore std::string nome; int livello; public: int Livello() const { return livello; } const std::string& Nome() const { return nome; } std::string Nome() const { return nome; } }; Metodi speciali: setters ● Dati sempre privati ● Metodi setters permettono di modificare i dati privati Non sono const per definizione, accettano un parametro Vanno definiti solo quando si vuole far cambiare lo stato dall'esterno in modo controllato Esempio class Serbatoio { private: std::string nome; int livello; public: void SetLivello(int livello_) { livello = livello_; } void SetNome(const std::string& nome_) { nome = nome_; } }; OOP in C++: esercizio ● Completare la classe Rettangolo e Punto vista in precedenza Aggiungere costruttori Aggiungere main che costruisce rettangolo e ne stampa area, perimetro e centro OOP in C++: esercizio ● Realizzare del software che permetta di effettuare calcoli con numeri complessi. Deve essere possibile sommare o moltiplicare due numeri complessi. – Usare la programmazione ad oggetti – Classe NumeroComplesso ● ● ● ● – Stabilire dati membri e metodi da realizzare Stabilire la loro visibilità Implementare i costruttori che ritenete necessari Implementare i metodi Nota (a+ib)*(c+id) = (ac -bd) + i(bc+ad) OOP in C++: esercizio ● PARTE 1 Si deve realizzare una classe che realizza un generatore casuale di numeri interi (usando la funzione rand() come generatore sottostante). Deve essere possibile inizializzare il generatore con un seme o richiedere un nuovo numero casuale. ● Effettuate il design della classe ed implementatelo in C++. Chiamatela dal main, stampando i primi 100 numeri generati. PARTE 2 Come PARTE 1 ma si deve ritornare un float e deve essere possibile specificare il min e max dell'intervallo tra cui i numeri devono stare. OOP in C++: esercizio ● PARTE 3 Definire ed implementare una classe che defisce un polinomio di grado 2 y = Ax2 + Bx + C La classe deve permettere di inizializzare A,B,C. La classe deve permettere di calcolare y dato x. La classe deve permettere di calcolare le radici del polinomio (-B +/- √(B2 – 4AC)/2A)