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)