38
www.manuelscapolan.it LEZIONE 02

OOP with C#

Embed Size (px)

DESCRIPTION

La programmazione ad oggetti in C#: incapsulamento, ereditarietà e polimorfismo con esempi di codice ed esercizi.

Citation preview

Page 1: OOP with C#

www.manuelscapolan.it

LEZIONE 02

Page 2: OOP with C#

2C# è un linguaggio orientato agli oggetti

Page 3: OOP with C#

• 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

Page 4: OOP with C#

• 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

Page 5: OOP with C#

• 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

Page 6: OOP with C#

• Possono essere definiti per una stessa

classe più costruttori (in overloading)

ed è possibile richiamarli tramite la

parola chiave this

Overloading costruttore

6

Page 7: OOP with C#

• 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

Page 8: OOP with C#

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

Page 9: OOP with C#

• 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

Page 10: OOP with C#

• In C# 3.0 gli oggetti possono essere

inizializzati direttamente nella chiamata

al costruttore:

Object initializers

10

Non necessariamente deve essere un costruttore vuoto

Page 11: OOP with C#

• 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)

Page 12: OOP with C#

• 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

Page 13: OOP with C#

• 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

Page 14: OOP with C#

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

Page 15: OOP with C#

• 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

Page 16: OOP with C#

• 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

Page 17: OOP with C#

• 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

Page 18: OOP with C#

• 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

Page 19: OOP with C#

• 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

Page 20: OOP with C#

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

Page 21: OOP with C#

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

Page 22: OOP with C#

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

Page 23: OOP with C#

• 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

Page 24: OOP with C#

• 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 …

Page 25: OOP with C#

• 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.

“ “

Page 26: OOP with C#

• Consideriamo l’ereditarietà tra

quadrato e rettangolo …

Violazione principio di Liskov

26

Il client conosce solo la classe base rettangolo

Page 27: OOP with C#

• Vediamo come sostituire uno switch per rendere il

nostro codice più flessibile, mantenibile e pulito:

Applicare il polimorfismo

27

Page 28: OOP with C#

• 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

Page 29: OOP with C#

• Una interfaccia è un insieme di membri

astratti che una classe deve

implementare per supportare un

determinato comportamento

Interfacce

29

definizione

implementazione

Page 30: OOP with C#

• 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

Page 31: OOP with C#

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:

Page 32: OOP with C#

• 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

Page 33: OOP with C#

• Esempio di gerarchia di classi:

Composizione vs Ereditarietà

33

Classe base astratta

Classi derivate

Page 34: OOP with C#

• Regola: incapsula ciò che varia …

Composizione vs Ereditarietà

34

La classe non è più astratta e ha un nuovo membro …

Page 35: OOP with C#

• L’interfaccia specifica ciò che varia

Composizione vs Ereditarietà

35

Page 36: OOP with C#

• 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

Page 37: OOP with C#

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

Page 38: OOP with C#

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