La programmazione ad oggetti (OOP)

Documenti analoghi
Il paradigma OO e le Classi

Laboratorio di programmazione

Programmazione Orientata agli Oggetti

Introduzione al C++ Corso di C++ INFN LNS 13 Dicembre Corrado Santoro

Classe Squadra. #include <iostream> using namespace std;

INTRODUZIONE ALLA PROGRAMMAZIONE

Programmazione orientata agli oggetti. Ivan Lanese

Programmazione ad oggetti

Informatica e Laboratorio di Programmazione C++ Object Oriented Programming Alberto Ferrari

Classi. Oggetti e classi. Creazione e inizializzazione di oggetti in C++ Distruzione di oggetti in C++

Programmazione ad Oggetti

Corso di Algoritmi e Strutture dati Programmazione Object- Oriented in Java (Parte I)

Definizione di classi. Walter Didimo

Informatica 1 Tipi e dichiarazioni in C++ C++ - Tipi e dichiarazioni 1

La scrittura di un programma Modellizzazione del programma Scrittura del codice Esercizi. Sperimentazioni I. Alberto Garfagnini, Marco Mazzocco

Corso di Programmazione ad Oggetti

La scrittura di un programma Modellizzazione del programma Scrittura del codice Esercizi. Sperimentazioni I. Alberto Garfagnini, Marco Mazzocco

Client - Interfaccia - Implementazione

L AMBIENTE CODE BLOCKS E L IO

Programmazione Java Struttura di una classe, Costruttore, Riferimento this

14 - Metodi e Costruttori

Programmazione con Java

Introduzione al linguaggio C Funzioni

PROGRAMMA = ALGORITMO

ereditarietà e polimorfismo

La classe std::vector della Standard Template Library del C++

Corso sul linguaggio Java

Perché il linguaggio C?

Transcript:

Oggetti e Classi (CAP 10) Alberto Garfagnini, Marco Mazzocco Università degli studi di Padova 30 Novembre 2011 La programmazione ad oggetti (OOP) È un approccio concettuale alla programmazione (indipendente dal linguaggio utilizzato) Il linguaggio C++ aggiunge nuovi elementi rispetto al C che permettono di implementare con facilità tale approccio. Gli aspetti più importanti di OOP sono: 1. Abstrazione 2. Incapsulamento e Data Hiding 3. Polimorfismo 4. Ereditarietà 5. Riutilizzo del Codice La Classe è lo strumento più importante del C++ per implementare la programmazione ad oggetti.

Astrazione e Classi È il passo importante per rappresentare l informazione come interfaccia con l utilizzatore: 1. si astraggono le operazioni essenziali di un problema; 2. si esprime la soluzione in quei termini. Es: Poligoni regolari Def. rappresentazione (dati): 1. numero di lati 2. lunghezza di un lato Def. interfaccia (azioni): 1. calcolare l area 2. calcolare il perimetro Es: Vettore nel piano Def. rappresentazione (dati): 1. coordinate (x, y) 2. coordinate (ρ,φ) 3. rappr (POLARE/CARTESIANA) Def. interfaccia (azioni): 1. imposta coordinate 2. imposta rappresentazione 3. somma due Vettori 4. sottrai due Vettori 5. moltiplica Vettore per costante Astrazione e Classi (2) La Classe è il veicolo per tradurre una astrazione in un tipo definito dal programmatore Permette di combinare insieme la rappresentazione dei dati e i metodi per manipolarli la scrittura di una classe comporta la specifica di 1. una class declaration, che descrive i dati che compongono l oggetto come data members e l interfaccia pubblica come member functions, chiamate anche metodi 2. una class method definition, che descrive come sono implementate le funzioni membri della classe Class Declaration Methods Definition Overview della Classe Implementazione Dettagliata

Sviluppo di una Classe Tipicamente, durante il disegno di una nuova classe (i.e. un nuovo tipo) si procede per passi successivi e si scrivono separatamente 1. un file header (es poligono.h) contiene l interfaccia tra la classe e l utilizzatore, sotto forma di definizione della classe. si compone di una parte pubblica accessibile dall utilizzatore e privata disponibile soltanto ai metodi della classe 2. un file sorgente (es poligono.cxx) contiene il codice, vero e proprio, che implementa i metodi della classe. deve rispettare tutte le definizioni (prototipi) che sono stati definiti dall interfaccia Es. Classe Poligono. File poligono.h // File: poligono.h #ifndef POLIGONO_H #define POLIGONO_H class Poligono private : int n_lati; double lato; void imposta_valori(double lung_lato, int nlati); double calcola_area(); double calcola_perimetro(); double stampa(); ; // Importante il punto-e-virgola #endif

Commenti alla classe Poligono La parola chiave class definisce un nuovo tipo e permette di dichiarare variabili, chiamate oggetti o istanze della classe Poligono Poligono quad_1, pent_1; definiscono due oggetti quad_1 e pent_1 come istanze della classe Poligono Le parole chiave private e public definiscono la modalità di accesso ai membri della classe (varibili e funzioni). Un programma che utilizza un oggetto di una classe può accedere direttamente soltanto alla sezione pubblica della classe Accedere ai membri privati della classe è possibile soltanto tramite funzioni pubbliche Per accedere alle variabili n_lati e lato bisogna passare attraverso il metodo pubblico imposta_valori Questo meccanismo di isolamento dei dati della classe prende il nome di data hiding Es. Classe Poligono. File poligono.h parola class identifica la definizione della classe il nome della classe diventa un nuovo tipo parola private identifica membri della classe ai quali si può avere accesso solo dalla parte pubblica (data hiding) class Poligono private : int n_lati; double lato; i membri della classe possono essere tipi o funzioni parola public identifica membri della classe che costituiscono l interfaccia pubblica della classe (abstraction) void ; imposta_valori(double llato, int nlati); double calcola_area(); double calcola_perimetro(); double stampa();

Implementiamo le funzioni, metodi della classe Per completare la scrittura delle della classe dobbiamo scrivere il codice per i metodi specificati nella dichiarazione della classe (file poligono.h). le definizioni dei metodi sono simili alle definizioni delle funzioni regolari del C++: ogni funzione ha un header e un corpo con il codice. una funzione può avere argomenti e ritornare un tipo ma soprattutto, nel definire un metodo di una classe, utilizzare l operatore :: per identificare la classe alla quale il metodo appartiene i metodi della classe posso accedere alla componente privata della classe Es. Classe Poligono. File poligono.cxx (1) // File: poligono.cxx #include <iostream> #include "poligono.h" void Poligono::imposta_valori(double llato, int nlati) lato = llato; n_lati = nlati; double Poligono::calcola_perimetro() return n_lati * lato; double Poligono::calcola_area() if (n_lati > 2 and n_lati <6) double area = n_lati * lato * lato / 4.; return area/tan(m_pi/n_lati);

Es. Classe Poligono. File poligono.cxx (2) void Poligono::stampa() using namespace std; switch (n_lati) case 3: cout << "Triangolo" << endl; break; case 4: cout << "Quadrato" << endl; break; case 5: cout << "Pentagono" << endl; break; default: cout << "Poligono sconosciuto. "; cout << "Numero lati: " << n_lati << endl; break; return; Usare le classi Vogliamo ora scrivere un programma che utilizza la classe definita in precedenza il C++ rende l utilizzo delle classi, e la creazione di oggetti, il più simile possibile all utilizzo dei tipi di base come int e char si crea un istanza della classe dichiarando una variabile dei tipo classe, oppure utilizzando l operatore new per allocare dinamicamente un oggetto del tipo classe è possibile passare oggetti di una classe a funzioni definite dall utente, ritornarli come valori di ritorno e assegnare un oggetto ad un altro è persino possibile istruire cin e cout a riconoscere gli oggetti di una classe e persino fornire una conversione automatica tra oggetti di classi simili vediamo un esempio di utilizzo

// test_poligono.cxx - Prova la classe Poligono #include <iostream> #include "poligono.h" int main( ) using namespace std; Poligono tri; tri.imposta_valori(2.5, 3); Poligono qua; qua.imposta_valori(2.5, 4); $ g++ -c poligono.cxx $ g++ test_poligono.cxx poligono.o./a.out Poligono: Triangolo Area : 2.70633 Perimetro : 7.5 Poligono: Quadrato Area : 6.25 Perimetro : 10 cout << "Poligono: "; tri.stampa(); cout << "Area : " << tri.calcola_area() << " Perimetro : " << tri.calcola_perimetro() << endl; cout << "Poligono: "; qua.stampa(); cout << "Area : " << qua.calcola_area() << " Perimetro : " << qua.calcola_perimetro() << endl; return 0; Costruttori e Distruttori di Classi Riguardiamo la definizione della classe Poligono subito dopo aver istanziato un oggetto della classe con l istruzione Poligono tri; è necessario invocare un metodo pubblico per inizializzare le variabili della classe (della sezione private) tri.imposta_valori(2.5, 3); altrimenti le variabili n_lati e lato non sono correttamente inizializzate ai valori voluti inoltre l unico modo per impostare dei valori è tramite un metodo dell interfaccia pubblica (perchè le variabili sono membri della parte private) il C++ fornisce una maniera per inizializzare un oggetto definendo dei metodi speciali costruttori e distruttori invocati ogni volta che si istanzia un oggetto di una classe o che l oggetto venga eliminato dalla memoria (e quindi non è più disponibile nel programma)

Costruttori di Default Tutte le volte che creiamo un oggetto Poligono tri; viene invocato un metodo default constructor se il metodo non esiste nell interfaccia della classe (header file) viene fornito dal compilatore nella fase di compilazione il metodo è vuoto (non contiene codice): // File: poligono.h class Poligono Poligono(); ; // File: poligono.cxx Poligono::Poligono() Costruttori e overloading Il default constructor viene invocato tutte le volte che si istanzia un oggetto senza passare valori di inzializzazione Poligono tri; È possibile definire altri costruttori, tramite l overloading // File: poligono.h class Poligono Poligono(); Poligono(double llato, int nlati); ; // File: poligono.cxx Poligono::Poligono(double llato, int nlati) lato = llato; n_lati = nlati; Poligono::Poligono() lato = 0.0; n_lati = 0;

Costruttori Nel disegnare una classe, scrivere sempre un costruttore di default in modo da inzializzare in maniera implicita tutti i membri della classe Poligono tri; Poligono qua = Poligono(); // chiama implicitamente // il default constructor // lo chiama esplicitamente Poligono * apo = new Poligono; // lo chiama implicitamente Poligono * penta = new Poligono(12.5, 5); // chiama un altro // constructor Tutte le volte che si invoca implicitamente il costruttore di default non si usano le parentesi Distruttori di Classi Quando si crea un oggetto con un costruttore, il programma si impegna a tenere traccia dell oggetto fino a quando scade in quel momento il programma invoca un metodo speciale chiamato distruttore che ha lo scopo di liberare eventuale memoria dinamica allocata dai metodi costruttori. // File: poligono.h class Poligono ~Poligono(); ; // File: poligono.cxx Poligono::~Poligono() std::cout << "Distruttore"; std::cout << std::endl; Il distruttore viene invocato automaticamente se un oggetto va out-of-scope non deve essere chiamato direttamente dal programma

Es. Classe Poligono modificata. File poligono2.h // File: poligono.h #ifndef POLIGONO_H #define POLIGONO_H class Poligono private : int n_lati; double lato; Poligono(double lung_lato, int nlati); // spec constructor Poligono(); // def constructor ~Poligono(); // destructor double calcola_area(); double calcola_perimetro(); double stampa(); ; #endif Es. Classe Poligono. File poligono2.cxx (1) // File: poligono.cxx #include <iostream> #include "poligono2.h" Poligono::Poligono() cout << "Default constructor called"; lato = 0.0; n_lati = 0; Poligono::Poligono(double llato, int nlati) cout << "Specialized constructor called"; lato = llato; n_lati = nlati; Poligono::~Poligono() cout << "Destructor called";

$ g++ -c poligono2.cxx $ g++ test_poligono2.cxx poligono2.o // test_poligono2.cxx - Prova la classe Poligono #include <iostream> #include "poligono.h" int main( ) using namespace std; Poligono tri = Poligono(2.5, 3); Poligono qua(2.5, 4); Poligono pen;./a.out Specialized constructor called Specialized constructor called Default constructor called Poligono: Triangolo Area : 2.70633 Perimetro : 7.5 Poligono: Quadrato Area : 6.25 Perimetro : 10 Destructor called Destructor called Destructor called cout << "Poligono: "; tri.stampa(); cout << "Area : " << tri.calcola_area() << " Perimetro : " << tri.calcola_perimetro() << endl; cout << "Poligono: "; qua.stampa(); cout << "Area : " << qua.calcola_area() << " Perimetro : " << qua.calcola_perimetro() << endl; return 0;