Upload
manuel-scapolan
View
4.875
Download
12
Embed Size (px)
DESCRIPTION
La programmazione ad oggetti in C#: incapsulamento, ereditarietà e polimorfismo con esempi di codice ed esercizi.
Citation preview
www.manuelscapolan.it
LEZIONE 02
2C# è un linguaggio orientato agli oggetti
• Una classe è l’astrazione di un concetto,
spesso riconducibile a entità del mondo reale
• La dichiarazione ne definisce i membri divisi
tra caratteristiche (attributi o campi) e
funzionalità (metodi)
Classi
3
• La classe rappresenta lo “stampo” con
cui vengono creati gli oggetti
• Un oggetto è detto istanza di una
classe dalla quale prende struttura e
funzionalità
• Per creare un oggetto si utilizza un
costruttore della classe richiamato
dalla parola chiave new
Classi e istanze
4
• E’ un metodo senza valore di ritorno,
con lo stesso nome della classe
• E’ utilizzato per inizializzare i campi
minimi che rendono valido un oggetto
• Se non definito il compilatore ne crea
uno senza parametri
Costruttore
5
• Possono essere definiti per una stessa
classe più costruttori (in overloading)
ed è possibile richiamarli tramite la
parola chiave this
Overloading costruttore
6
• L’interazione tra le entità di un dominio
avviene tramite lo scambio di
messaggi (ovvero chiamate ai metodi)
Scambio di messaggi
7
Destinatario del messaggioParametri
Nome del messaggio
IncapsulamentoUno dei principi della programmazione ad oggetti prevede di
nascondere le informazioni interne (information hiding) di una
classe al fine di mantenere uno stato consistente
18
• Per proteggere lo stato interno di una
classe si utilizzano le proprietà:
• In C# 3.0 possiamo inizializzarle così:
Proprietà
9
Modificatori di accesso
Prima di assegnare un valore posso eseguire una validazione
Posso personalizzare il modificatore di accesso
• In C# 3.0 gli oggetti possono essere
inizializzati direttamente nella chiamata
al costruttore:
Object initializers
10
Non necessariamente deve essere un costruttore vuoto
• Sono condivisi da tutte le istanze di
una classe, possiamo avere:
Membri di classe o static
11
– Campi statici
– Costruttori statici (inizializzazione
che avviene una volta sola per tutte le eventuali istanze e prima
del costruttore dell’oggetto)
– Metodi statici (es. String.Format)
– Proprietà statiche
– Classi statiche (nessun membro
di istanza)
• In C# 2.0 è possibile scrivere una classe
in due file distinti e attraverso la parola
chiave partial ci penserà il
compilatore ad unirle in un’unica
definizione (vedi designer.cs)
Partial Class
12
• Con i metodi parziali è possibile creare
nelle classi dei punti di estensione
indispensabili nella code generation
• I metodi parziali sono disponibili con
C# 3.0
Partial Method
13
1) Non possono avere un valore di ritorno
2) Sono privati
3) Non possono avere parametri in output
EreditarietàPosso derivare nuove classi a partire da altre già definite. La
classe derivata mantiene i metodi e gli attributi della classe da
cui deriva (classe base). Posso aggiungere nuovi attributi e
metodi e modificare il comportamento di quelli esistenti
214
• In C#, contrariamente a Java, posso
ereditare da una sola classe
• Non utilizzate mai l’ereditarietà con
l’unico scopo di riutilizzare il codice!
Ereditarietà singola
15
Classe base
Classi derivate
• Se definiamo nella classe base dei
metodi virtual possiamo ridefinire nelle
derivate l’implementazione tramite
override
Metodi virtual e override
16
Richiamo l’implementazione della classe base
• Se un metodo non è virtual non posso
fare l’override, ma posso definire un
metodo con la stessa firma tramite la
parola chiave new
Metodi new
17
• Molte volte non ha senso avere una istanza
della classe base se non per ottenere una
delle sue derivate
• Una classe base definita solo per essere
derivata è una “classe astratta”, non può
essere istanziata anche se può comunque
contenere attributi e implementare metodi
Classi abstract
18
• E’ possibile impedire che una classe possa
essere ereditata definendola sealed
• Magari per evitare che un override possa
negativamente o erroneamente
modificarne l’utilizzo
• Contro: complica il testing (mocking)
Classi sealed
19
1) In un namespace Library definire le entità libro e
autore (Book e Author). Specificare per l’autore
nome e cognome. Il libro ha le seguenti
caratteristiche: titolo, ISBN, data pubblicazione,
casa editrice, autore/i e numero pagine.
2) Definire per il libro una serie di costruttori per
inizializzarlo a partire da:• Titolo, ISBN e data di pubblicazione
• Oltre ai precedenti anche un autore o più. Nel caso di più
autori che sia possibile specificarli come insieme o uno alla
volta
3) Eseguire l’override di ToString() per stampare a
video la copertina. Inizializzare quindi nel main del
programma un insieme di libri con rispettivi autori e
stampare in console le loro copertine (utilizzare la
classe ArrayList)
Esercizi
20
4) Realizzare un extension method che consenta di
sapere se un determinato libro è multi-autore
5) Aggiungere alla classe autore un metodo virtual
(DescriptionToCover) che ritorna il nome completo
6) Definire una classe co-autore (CoAuthor) che
deriva dalla classe autore e re-implementa il
metodo virtuale mettendo come prefisso la scritta
(“Forewords by “)
7) Impedire la possibilità di poter derivare dalla classe
co-autore
8) Aggiungere un co-autore a un libro e verificare
che venga correttamente stampato in copertina
Esercizi
21
PolimorfismoL’override di un metodo virtual di una classe base nelle sue
derivate permette di chiamare poi quel metodo su classi diverse
senza dover conoscere a compile-time la specifica classe
derivata che lo implementa
322
• Posso utilizzare le classi derivate
tramite un riferimento alla classe base
Classe base e classi derivate
23
accedo al metodo della classe derivata tramite la classe base
• Con il polimorfismo a compile-time
perdiamo il tipo concreto di una classe
• Per conoscere a compile-time il tipo di
una classe possiamo utilizzare is e as
Di che tipo è questa classe? as e is
24
devo fare comunque un cast per poter usare l’istanza della classe derivata …
• Devo poter usare una classe derivata
senza conoscerla … ovvero usandola
per mezzo della classe base
• Ottengo un minor accoppiamento fra
moduli e un’ereditarietà più solida
Principio di sostituibilità di Liskov
25
If for each object o1 of type S there is an object o2 of
type T such that for all programs P defined in terms of T,
the behavior of P is unchanged when o1 is substituted
for o2 then S is a subtype of T.
“ “
• Consideriamo l’ereditarietà tra
quadrato e rettangolo …
Violazione principio di Liskov
26
Il client conosce solo la classe base rettangolo
• Vediamo come sostituire uno switch per rendere il
nostro codice più flessibile, mantenibile e pulito:
Applicare il polimorfismo
27
• Proviamo ad applicare il polimorfismo:
Applicare il polimorfismo
28
La classe principale diventa astratta
Vengono definite delle derivate
Nel client la classe derivata sarà creata tramite factory o attraverso dependencyinjection
• Una interfaccia è un insieme di membri
astratti che una classe deve
implementare per supportare un
determinato comportamento
Interfacce
29
definizione
implementazione
• Ereditarietà multipla si può!
• Una classe può implementare più di
una interfaccia e una interfaccia può
ereditare da più interfacce
contemporaneamente
Ereditarietà tra interfacce
30
Interfacce vs Classi abstract
31
Classe astratta (abstract) Interfaccia
Definisce membri astratti che le derivate devono implementare
Contiene solo membri astratti che devono essere implementati
Posso aggiungere nuovi membri non-abstract senza modificare le classi derivate
Estendere una interfaccia comporta la modifica di tutte le classi che la implementano
Può avere uno stato al quale si può accedere dalla derivata
Non può avere uno stato, ma posso definire delle proprietà senza implementazione
Posso definire tramite metodi virtuali delleimplementazioni predefinite
I metodi non possono contenere implementazioni
Posso derivare solo da una classe astratta, ovvero single-inheritance
Una classe può implementare più interfacce e una interfaccia può ereditare da più interfacce, ovvero multiple-inheritance
• Principali differenze:
• Una classe può avere come membro
un’altra classe (composizione o delega)
• Se la classe membro esiste
esternamente alla relazione si parla di
aggregazione
• Segreto per vivere meglio: preferite la
composizione all’ereditarietà!
Composizione vs Ereditarietà
32
• Esempio di gerarchia di classi:
Composizione vs Ereditarietà
33
Classe base astratta
Classi derivate
• Regola: incapsula ciò che varia …
Composizione vs Ereditarietà
34
La classe non è più astratta e ha un nuovo membro …
• L’interfaccia specifica ciò che varia
Composizione vs Ereditarietà
35
• Obiettivo principale di un buon design è
ottenere un’alta coesione e un basso
accoppiamento
• … e che cosa vuol dire?!
– Coesione: correlazione tra le funzionalità messe a
disposizione da un modulo (sia esso un insieme di
metodi di una classe, un insieme di classi, una
gerarchia, etc.)
– Accoppiamento: (o dipendenza) si intende il
grado con cui ciascun modulo fa affidamento su
ciascuna delle altre componenti del programma
Come costruire le nostre classi
36
9) Riscrivere l’esempio dello switch
utilizzando la composizione al posto
del polimorfismo
10)Implementare nella classe libro
l’interfaccia IComparable per
ordinare i libri per titolo
Esercizi
37
Slide 2 : http://www.flickr.com/photos/rmlowe/3281353786/
Slide 8 : http://www.flickr.com/photos/sinthonia/4439404454
Slide 14 : http://www.flickr.com/photos/pardeshi/1514977212
Slide 22 : http://www.flickr.com/photos/seelilie/4767842760
CreditsLe immagini contenute in questa presentazione
hanno licenza Creative Commons
Contacts MANUEL SCAPOLAN
website: www.manuelscapolan.it
twitter: manuelscapolane-mail: [email protected]
38