C# LE CLASSI O.O.P. = Object Oriented Programming oggetto classe oggetto istanziato l'oggetto istanza della classe classe istanziare oggetti

Save this PDF as:
 WORD  PNG  TXT  JPG

Dimensione: px
Iniziare la visualizzazioe della pagina:

Download "C# LE CLASSI O.O.P. = Object Oriented Programming oggetto classe oggetto istanziato l'oggetto istanza della classe classe istanziare oggetti"

Transcript

1 C# LE CLASSI C# è un linguaggio orientato agli oggetti (O.O.P. = Object Oriented Programming). Un oggetto è la realizzazione in pratica di un qualcosa descritto in teoria. Esso ha delle caratteristiche, delle proprietà, degli attributi e dei metodi per utilizzarlo. Quando un architetto progetta una casa, ne fa il progetto su carta tramite un disegno che ne descrive le dimensioni, le caratteristiche ed eventualmente le tecniche di costruzione. Questo lavoro rappresenta la descrizione teorica di un oggetto (Casa) che dovrà essere costruito. In questo esempio, il progetto rappresenta la classe, mentre la casa realmente costruita, rappresenta l'oggetto vero e proprio. Usando la terminologia ad hoc, si dice che è stato istanziato l'oggetto casa cioè è stata creata una istanza della classe (progetto) Casa. In parole povere le classi sono definizioni usate per la creazione di oggetti. Dal progetto dell'architetto, volendo, si possono costruire più case. Per le classi, il concetto è lo stesso; da una classe si possono istanziare uno o più oggetti, dipende da quanti oggetti dello stesso tipo abbiamo bisogno in una applicazione. Facciamo un esempio: la classe Studente descrive tutte le caratteristiche di uno studente, per es. il nome, il cognome, la provenienza, ecc.. Con una istanza della classe Studente, che chiameremo Alunno, creeremo effettivamente un oggetto reale a partire della classe e che potremo usare nel nostro programma. E' ovvio che in una aula di una scuola c'è più di un alunno, quindi istanzieremo più classi Studente per formare la nostra aula di oggetti Alunno. Per saper utilizzare al meglio un linguaggio orientato agli oggetti, è necessario capire alcune caratteristiche molto importanti. Le caratteristiche principali di un linguaggio O.O.P. sono: l'incapsulamento, il polimorfismo, l'ereditarietà. L'incapsulamento è un concetto tramite il quale una classe consente di incorporare dati e tutti i metodi (funzioni) che li gestiscono. Ha la possibilità di nascondere questi elementi interni al mondo esterno. Le classi hanno dei meccanismi tali da rendere fruibili questi dati senza che l'utente sia a conoscenza di come sono strutturati. Nella maggior parte dei casi, è cosa positiva non rendere pubblici i dati di una classe perchè un utente (programmatore) deve solamente utilizzarla, non sapere cosa e come i dati sono stati impostati. Il codice del programma non sarà in grado di accedere ai dati della classe. Una classe avrà al suo interno dei metodi (li vedremo più avanti) per renderli disponibili. Cosi facendo, il programmatore della classe potrà modificare liberamente la struttura senza che il codice del programma ne subisca conseguenze. Il polimorfismo è la capacità di assumere molte forme. Nei programmini che abbiamo visto negli esempi, abbiamo fatto uso di un metodo per stampare sul monitor: Console.WriteLine("...0",var);. L'argomento tra parentesi graffe 0, si riferisce alla variabile var che dovrà essere stampata. Ma il metodo non sa di che tipo è la variabile che deve stampare. Il metodo in questione è polimorfico cioè si adatta alla maggior parte dei tipi che gli vengono passati. Lo stesso metodo può avere più di una variabile da stampare e lo fa tranquillamente appunto perchè è polimorfica. L'ereditarietà è il concetto un pò più complesso della programmazione orienteta agli oggetti. E' la possibilità di creare una classe che eredita le caratteristiche da un'altra classe espandendone le funzionalità. Per esempio possiamo creare una classe generale che chiameremo Autoveicoli che raggruppa tutti i veicoli che hanno in comune alcune proprietà e funzionalità. Possiamo creare una classe Autovettura che eredita le proprietà e funzionalità comuni e in più possiamo aggiungere proprietà e funzionalità tipiche di un'autovettura, per esempio marca, modello, motorizzazione ecc.... Abbiamo quindi creato una classe che ha ereditato le funzionalità dalla classe "genitore" e ne abbiamo espanso le funzionalità aggiungendone di nuove non presenti nella classe "genitore". L'ereditarietà è un concetto molto potente che ci consente di creare oggetti (classi) molto complessi e pieni di funzionalità. Avremo modo di parlarne in modo più approfondito quando creeremo classi personalizzate. 1

2 Non preoccupatevi se avete incontrato qualche difficoltà nell'apprendere questi concetti, è normale, man mano che andremo avanti si chiariranno. Definizione di una classe. Per definire una classe, abbiamo bisogno di una intestazione rappresentata dalla parola chiave class e da un corpo che ne racchiude il contenuto, così: class NomeClasse elementi definiti nel corpo dove il NomeClasse o identificatore rappresenta il nome che vogliamo dare alla classe. E utile dare un nome significativo alla classe che ne descriva l impiego. Ad esempio possiamo definire la classe Studente: elementi definiti nel corpo dal suo identificatore (Studente), capiamo al volo che si tratta di qualcosa che a che fare con una persona; un altro esempio: class Autovettura elementi definiti nel corpo anche in questo caso si capisce, dall identificatore (Autovettura), che avremo a che fare con un veicolo. Una volta creata una classe, non possiamo utilizzarla senza dichiararla. Siamo di fronte ad un tipo particolare di dato che noi abbiamo realizzato (progetto) e da questo dobbiamo creare un oggetto che lo rappresenti e che possiamo utilizzare. La dichiarazione (istanza) di una classe avviene in maniera quasi banale, cioè faremo così: NomeClasse nomeoggetto = new NomeClasse(); ritornando agli esempi che ho fatto prima, possiamo creare (istanziare) un oggetto Studente che chiameremo alunno così: Studente alunno = new Studente (); allo stesso modo per un oggetto Autovettura che chiameremo miamacchina: Autovettura miamacchina = new Autovettura (); abbiamo creato due oggetti, alunno di tipo Studente e miamacchina di tipo Autovettura. Ma questi oggetti non servono a molto in una applicazione, sono oggetti "vuoti", cioè non contengono al loro interno qualcosa che li faccia distinguere tra loro. Per esempio un alunno avrà pure un nome ed un cognome, la miamacchina avrà pure una cilindrata, una marca, un colore, ecc.. Ebbene, per avere queste informazioni, dobbiamo necessariamente inserire all interno del loro corpo delle variabili che ci indicano tali informazioni, o per meglio dire, tali proprietà. Tali variabili vengono definite, in gergo tecnico, variabili istanza o campi istanza, ed essendo definite a livello classe, e quindi visibili a tutti i metodi della classe vengono dichiarate per convenzione con la lettera iniziale maiuscola, per contraddistinguerle dalle variabili locali utilizzate all interno dei metodi. Facciamo subito un esempio di come vengono dichiarati i campi istanza. Prendiamo la classe Studente che qui ripropongo: elementi definiti nel corpo 2

3 senza ombra di dubbio possiamo affermare che uno studente ha un nome ed un cognome che potremmo rappresentare tramite due variabili di tipo stringa. Ecco come: // definisco due campi istanza string Nome; string Cognome; Ora la classe ha un aspetto più concreto ma non ancora utilizzabile. Così com è, pur essendo una classe a tutti gli effetti, se istanziamo un oggetto Alunno, non potremo mai sapere come si chiama. I suoi campi istanza non saranno fruibili dal codice esterno perché così come sono stati dichiarati diventano automaticamente privati (in gergo private) alla classe e nessun codice può accedervi. Qui entrano in gioco i modificatori di accesso. Dobbiamo fare in modo che questi campi istanza diventino pubblici, cioè accessibili a tutto il codice utente. Questa è la nuova classe: // definisco due campi istanza public string Nome; public string Cognome; Finalmente ora la nostra classe è pronta per l uso. Abbiamo inserito il modificatore public con l intenzione di utilizzare i campi istanza all esterno della classe e quindi dal nostro programma. Come vedremo più avanti, i campi istanza con modificatore private potranno essere comunque manipolati tramite un costrutto molto semplice. Però adesso concentriamoci sulla nostra classe e vediamo come valorizzare questi campi. Per prima cosa dovremo istanziare un oggetto dalla classe tramite il quale accederemo ai campi istanza che abbiamo creato, quindi: Studente alunno = new Studente(); Per accedere ai campi istanza faremo uso di una particolare notazione, la notazione puntata in questo modo: alunno.nome = "Mario"; con questa istruzione, abbiamo assegnato al campo istanza Nome dell oggetto alunno la stringa "Mario". Allo stesso modo faremo per il cognome: alunno.cognome = "Rossi"; All assegnazione di un valore ad una variabile, ne corrisponde anche una lettura e nel nostro caso faremo l operazione inversa; se avessimo una variabile stringa chiamata per esempio datonome, potremo valorizzarla leggendo il valore memorizzato nel campo istanza del nostro oggetto: datonome = alunno.nome; i campi istanza sono delle normali variabili e quindi le possiamo manipolare come sappiamo. 3

4 A questo punto della trattazione, non ci resta che scrivere qualche riga di codice per vedere in azione la nostra classe: // questo programma usa la classe Studente using System; // la classe // campi istanza della classe public string Nome; public string Cognome; class Alunno // il programma public static void Main() // istanzio la classe Studente alunno = new Studente(); // valorizzo i campi dell oggetto alunno.nome = "Mario"; alunno.cognome = "Rossi"; // stampo i valori dei campi Console.WriteLine("\nIl nome dell alunno è 0 1", alunno.nome, alunno.cognome); // attendo un INVIO per chiudere il programma Console.ReadLine(); Copiate e compilate il codice. Questo è il risultato: il nome dell alunno è Mario Rossi Il programma appena scritto, pur non avendo nessuna utilità pratica se non quella di stampare delle stringhe, ci consente di capire come utilizzare una classe all interno di una applicazione. Per prima cosa, notiamo dove è posizionata la classe all interno del codice; viene posizionata subito dopo la direttiva (o le direttive) using e prima della dichiarazione della classe programma. All interno del metodo Main(), che rappresenta il punto di inizio del programma, troviamo l istruzione che istanzia la classe (riga 17) e quindi crea l oggetto alunno sul quale faremo le nostre operazioni. Le istruzioni delle righe 20 e 21 valorizzano rispettivamente il campo nome ed il campo cognome dell oggetto. Infine alla riga 24 troviamo l istruzione che effettua la stampa con una sintassi del tutto corretta. Nella prossima lezione, approfondiremo altri concetti molto importanti sulle classi come i metodi e le proprietà Nelle classi di esempio utilizzate nella precedente lezione, abbiamo utilizzato dei campi istanza (variabili della classe) che avevano il modificatore di accesso public con il quale il codice esterno alla classe poteva accedere direttamente ai loro valori. Nella normale programmazione orientata agli oggetti, è consigliabile garantire una maggiore "ristrettezza" riguardo l accesso ai campi istanza della classe. Con ristrettezza si intende cioè "mascherare" la natura e la struttura dei campi inclusi nella classe. L utilizzatore della classe non deve interessarsi di come sono stati creati e/o manipolati i campi istanza dell oggetto che dovrà gestire all interno di una applicazione, ma li dovrà solamente utilizzare. I progettisti di una classe, nascondono, rendendoli privati, tutti (o quasi) i campi istanza di una classe. La domanda nasce spontanea: "Se i campi vengono dichiarati privati (private), come si possono utilizzare all interno di una applicazione se non possiamo accedervi?". La risposta è nel capitolo seguente. 4

5 LE PROPRIETA Il C# mette a disposizione un costrutto particolare creato ad hoc per poter accedere indirettamente ai campi istanza di una classe: le proprietà. Con le proprietà, siamo in grado di accedere ai campi istanza sia in lettura che in scrittura; questa è la sintassi: public tipo nome_proprietà get return nome_campo; set nome_campo = value; La segnatura indica che la proprietà è public, quindi accessibile dal codice esterno alla classe, è dichiarata di un tipo tra quelli consentiti dal linguaggio e che è in stretta relazione con quello del campo istanza a cui farà riferimento ed infine ha un nome. Le parole chiave get e set consentono l effettivo accesso al campo istanza ed in particolare con: get Saremo in grado di leggere il contenuto del campo. Nel suo blocco di codice noterete la parola chiave return. Essa ci ritorna il valore del campo nome_campo (tra breve vedremo come). Questo consente al programmatore di valutare e decidere se necessario quale valore restituire, alterando il risultato a seconda di determinate condizioni nel corso dell esecuzione del programma. set Saremo in grado di assegnare un preciso valore al campo nome_campo tramite la parola chiave value. Questo consente al programmatore di controllare il valore da assegnare, evitando di utilizzare valori errati che comprometterebbero il funzionamento della classe stessa. Le proprietà possono contenere entrambe le sezioni (get/set) o solo una di esse, rendendole a sola lettura o sola scrittura. Per convenzione i nomi dei campi istanza che si riferiscono ad una proprietà vengono preceduti dal prefisso Var. NOTA: a seconda delle esigenze le proprietà possono non memorizzare il loro valore in una variabile, questo è molto frequente quando il loro valore è dipendente da quello di altre proprietà. Come al solito la teoria deve necessariamente lasciare spazio alla pratica che svelerà molto semplicemente i "retroscena" dell uso delle proprietà. Riprendiamo la classe Studente della lezione precedente e che qui riporto: // campi istanza della classe public string Nome; public string Cognome; 5

6 Ora la trasformeremo aggiungendovi tre proprietà: Nome, con riferimento al campo istanza/variabile VarNome in quanto memorizza il valore in VarNome Cognome, con riferimento al campo istanza/variabile VarCognome in quanto memorizza il valore in VarCognome NomeCompleto, senza riferimenti a campi istanza/variabili in quanto il suo valore è dipendente da Nome e Cognome Per prima cosa eliminiamo il modificatore public rendendo entrambi i campi privati. Ricordo che se ad un campo non diamo nessun modificatore di accesso, il campo diventa automaticamente private. Ora la classe si presenta così: // campi istanza privati della classe string VarNome; string VarCognome; Inseriamo le proprietà descritte sopra: // campo istanza privato della classe string VarNome; // definisco la proprietà per il campo Nome public string Nome // è dello stesso tipo del campo istanza get // per la lettura return VarNome; // ritorna il valore stringa del campo set // per l assegnazione VarNome = value; // assegno un valore stringa al campo // campo istanza privato della classe string VarCognome; // definisco la proprietà per il campo Cognome public string Cognome // è dello stesso tipo del campo istanza get // per la lettura return VarCognome; // ritorna il valore stringa del campo set // per l assegnazione VarCognome = value; // assegno un valore stringa al campo // definisco la proprietà per il campo NomeCompleto public string NomeCompleto get // per la SOLA lettura return VarCognome + + VarNome; // ritorna il nome completo // fine blocco di codice della classe 6

7 La classe è terminata ed è pronta all uso. Ma ora che i campi istanza sono "spariti", in che modo le proprietà verranno utilizzate nel codice? Le proprietà, come avete imparato, hanno un nome ed è proprio tramite il nome che accederemo ai campi. Le proprietà possono essere considerate come semplici variabili e come tali verranno usate nel codice. Normalmente quando assegniamo un valore ad una variabile siamo soliti scrivere, per esempio: numero = 124; oppure se vogliamo leggerne il contenuto scriviamo: num_libri = numero; con le proprietà faremo la stessa cosa ma con la variante che, avendo a che fare con un oggetto, dobbiamo utilizzare la notazione puntata (operatore punto). Per esempio se abbiamo istanziato un oggetto alunno tramite la classe Studente e vogliamo assegnargli un nome ed un cognome faremo così: // 1: per il nome alunno.nome = "Valentino"; // 2: per il cognome alunno.cognome = "Rossi"; // 3: per il nome completo ERRORE! alunno.nomecompleto = "Rossi"; le istruzioni, hanno effettuato una assegnazione di un valore per i campi privati della classe richiamando automaticamente il costrutto set attraverso le rispettive proprietà (Nome e Cognome). Il terzo esempio, quello relativo al NomeCompleto genererebbe un errore in quanto la proprietà NomeCompleto non è dotata di costrutto set, risultando di sola lettura. Al contrario, se vogliamo leggere i valori contenuti nei campi privati della classe sarà sufficiente inserire l accesso alla proprietà nel punto del codice in cui serve il rispettivo valore. L esempio seguente visualizza a video il valore di ciascuna delle tre proprietà: // 1: per il nome Console.WriteLine(alunno.Nome); // 2: per il cognome Console.WriteLine(alunno.Cognome); // 3: per il nome completo Console.WriteLine(alunno.NomeCompleto); le istruzioni richiamano automaticamente il costrutto get delle rispettive proprietà che: nel caso di Nome e Cognome: ci ritornerà il valore del campo privato associato tramite la parola chiave return nel caso di NomeCompleto: ci ritornerà il risultato del calcolo effettuato nel costrutto get, tramite la parola chiave return 7

8 E arrivato il momento di vedere in azione la nuova classe con questo semplice programmino. Copiate il listato, compilatelo e lanciatelo. // questo programma usa la classe Studente modificata using System; // campo istanza privato della classe string VarNome; // definisco la proprietà per il campo Nome public string Nome // è dello stesso tipo del campo istanza get // per la lettura return VarNome; // ritorna il valore stringa del campo set // per l assegnazione VarNome = value; // assegno un valore stringa al campo // campo istanza privato della classe string VarCognome; // definisco la proprietà per il campo Cognome public string Cognome // è dello stesso tipo del campo istanza get // per la lettura return VarCognome; // ritorna il valore stringa del campo set // per l assegnazione VarCognome = value; // assegno un valore stringa al campo // definisco la proprietà per il campo NomeCompleto public string NomeCompleto get // per la SOLA lettura return VarCognome + + VarNome; // ritorna il nome completo // fine blocco di codice della classe class Program // il programma public static void Main() // istanzio la classe Studente Alunno = new Studente(); // valorizzo le proprietà dell oggetto Alunno.st_nome = "Valentino"; Alunno.st_cognome = "Rossi"; // stampo i valori dei campi Console.WriteLine("\nIl nome dell alunno è 0 1", Alunno.st_nome, Alunno.st_cognome); // attendo un carattere qualsiasi // digitato per chiudere il programma Console.ReadLine(); // chiude il Main() // chiude il programma 8

9 I METODI Una classe può disporre oltre che di campi istanza e proprietà anche di metodi, intesi come funzionalità destinate a risolvere determinati problemi attinenti la classe. Un metodo può: contenere più di una istruzione, permettendo l esecuzione di azioni più complesse di quelle risolvibili mediante una proprietà ricevere uno o più parametri, intesi come variabili locali con ambito di visibilità legato al metodo stesso, da utilizzare per la risoluzione del problema restituire un solo risultato mediante un valore di ritorno, o più risultati mediante più parametri passati per riferimento DICHIARAZIONE Per dichiarare un metodo occorre specificare: ambito_visibilità tipo_risultato nome_metodo ([ref]tipo_param1 nome_param1,...) // istruzioni da compiere... L ambito di visibilità può essere uno di quelli conosciuti (public, private, ). Il tipo di risultato può essere un qualsiasi tipo primitivo (int, double, string,.) o classe. Deve corrispondere alla tipologia di dato che vogliamo far restituire al metodo. Se il metodo non restituisce nulla, deve corrispondere alla parola chiave VOID. Il nome del metodo deve soddisfare i criteri visti per variabili, proprietà e campi di istanza. I parametri non sono indispensabili, ma nel caso siano utilizzati occorre: o Specificare per ognuno il tipo e il nome o Nel caso debbano essere utilizzati anche per restituire un valore occorre anteporre al tipo la parola chiave REF. In questo caso il parametro non costituisce una copia del valore passato, ma un riferimento diretto alla variabile passata al momento della chiamata, che al termine dell esecuzione del metodo risulterà influenzata dai cambiamenti apportati nel metodo. o Separarli da una virgola nel caso siano più di uno NOTA: All interno della stessa classe possono coesistere metodi con lo stesso nome, ma si devono necessariamente differenziare per il NUMERO di parametri o per il TIPO. Questa possibilità viene chiamata OVERLOADING, cioè sovraccarico, è possibile definire metodi con lo stesso nome, che risolvono lo stesso problema, che utilizzano parametri in ingresso differenti. Nell esempio seguente viene implementato un metodo cercando di riassumere tutte le tipologie possibili. La classe Articolo dispone di due campi di istanza pubblici Prezzo e Sconto, vengono implementati alcuni metodi per il calcolo del prezzo scontato. La classe Program istanzia un oggetto di tipo Articolo e ne utilizza i relativi metodi. 9

10 class Articolo // Dichiarazione campi di istanza public double Sconto, Prezzo; // 1: Il metodo esegue il calcolo utilizzando i campi istanza // e visualizza il risultato direttamente sulla console public void PrezzoScontato() Console.WriteLine(Prezzo * (100 Sconto) / 100); // 2: Il metodo esegue il calcolo utilizzando i campi istanza // e RESTITUISCE il risultato alla funzione chiamante // NOTA: aggiungo R al nome per differenziarlo dal precedente in quanto // entrambi non dispongono di parametri public double PrezzoScontatoR() return (Prezzo * (100 Sconto) / 100); // 3: Il metodo esegue il calcolo utilizzando i parametri forniti // e visualizza il risultato direttamente sulla console public void PrezzoScontato(double aprezzo, double asconto) Console.WriteLine(aPrezzo * (100 asconto) / 100); // 4: Il metodo esegue il calcolo utilizzando i parametri forniti // e RESTITUISCE il risultato alla funzione chiamante // NOTA: aggiungo R al nome per differenziarlo dal precedente in quanto // entrambi dispongono dello stesso numero (2) e tipo di parametri (double) public double PrezzoScontatoR(double aprezzo, double asconto) return (aprezzo * (100 asconto) / 100); // 5: Il metodo esegue il calcolo utilizzando i campi istanza // e RESTITUISCE il risultato alla funzione chiamante mediante un parametro // passato per RIFERIMENTO (REFerence) public void PrezzoScontato(ref double aprezzoscontato) // Impone la modifica alla variabile passata per indirizzo aprezzoscontato = (Prezzo * (100 Sconto) / 100); class Program public static void Main() // Istanzia un oggetto di tipo Articolo Articolo art = new Articolo(); // Visualizza il prezzo scontato (metodo1) art.prezzoscontato(); // Visualizza il prezzo scontato (metodo2) Console.WriteLine(art.PrezzoScontatoR()); // Visualizza il prezzo scontato (metodo3) art.prezzoscontato(1000, 10); // Visualizza il prezzo scontato (metodo4) Console.WriteLine(art.PrezzoScontatoR(1000, 10)); // Visualizza il prezzo scontato (metodo5) double risultato = 0; art.prezzoscontato(ref risultato); // passaggio per riferimento Console.WriteLine(risultato); // visualizza modifica apportata nel metodo 10

11 I METODI COSTRUTTORI Ogni volta che viene istanziato un oggetto con la parola chiave new il frame work ricerca all interno della classe il metodo utilizzato per la sua costruzione, tale metodo viene detto costruttore. Il framework non impone la definizione di un costruttore per ogni classe definita dal programmatore, lasciando un altissimo grado di personalizzazione. Per ogni classe viene considerata l esistenza di un costruttore predefinito, che anche se non esplicitamente definito, può essere utilizzato per istanziare la classe. Il metodo costruttore, essendo chiamato in fase di creazione dell istanza, può essere utilizzato per compiere le operazioni iniziali relative alla classe, ad esempio l inizializzazione di alcune proprietà o campi di istanza. E possibile sottoporre i costruttori ad overload, come visto per i metodi normali, in questo modo si offre la possibilità di creare un istanza della classe utilizzando parametri diversi in fase di costruzione. DICHIARAZIONE public nome_classe ([ref]tipo_param1 nome_param1,...) [:this(...)] // istruzioni da compiere... L ambito di visibilità deve essere necessariamente public, per dare la possibilità di chiamare il costruttore dalla classe utilizzatrice (es. applicazione). Il nome del metodo DEVE essere necessariamente uguale a quello della classe. Il costruttore può avere o meno parametri, ma bisogna tenere conto di una cosa importante: se si definisce un costruttore con parametri si perde automaticamente la possibilità di utilizzare il costruttore predefinito, che se si ha la necessità di utilizzare andrà definito esplicitamente all interno della classe. Se all interno della classe sono dichiarati più costruttori è possibile chiamarne uno all interno della definizione di un altro, in modo da eseguire quelle che sono le istruzione previste dal metodo a cui si fa riferimento [:this( )] Nell esempio seguente vengono dichiarati più costruttori, in modo da offrire diverse possibilità per istanziare un nuovo oggetto di tipo Articolo : class Articolo // Dichiarazione campi di istanza public double Sconto, Prezzo; // 1: Costruttore vuoto // Inizializza i campi di istanza ai valori iniziali public Articolo () Sconto = 0; Prezzo = 0; // 2: Costruttore con parametri // Inizializza i campi di istanza ai valori indicati dai parametri public Articolo (double asconto, double aprezzo) Sconto = asconto; Prezzo = aprezzo; // 3: Costruttore con un solo parametro // Inizializza i campi di istanza ai valori iniziali mediante il richiamo del metodo // costruttore 1 e varia il campo Prezzo con quello indicato dal parametro aprezzo public Articolo (double aprezzo) : this() Sconto = asconto; 11

12 GLI EVENTI C# ha introdotto una semplificazione sostanziale della gestione degli eventi nella programmazione, rendendo il programmatore libero di inventare e definire eventi personalizzati all occorenza. Per evento si intende il verificarsi di una condizione particolare all interno di una classe durante la normale esecuzione del programma, alla quale associare una notifica da eseguire nella classe utilizzatrice (es. programma). Un esempio banale potrebbe essere il livello di scorta di un articolo di magazzino, al raggiungimento del livello di riordino impone all applicazione di eseguire una procedura specifica (vedi esempio più avanti). Ad ogni evento è associato un Handler (gestore), che consiste in una tipologia specifica di metodo utilizzato per gestirlo e riceverlo. C# mette a disposizione molti Handler, a seconda dell evento da catturare, ma per eventi standard esiste un handler generico di nome EventHandler. Altri gestori sono per esempio: KeyEventHandler che gestisce la pressione dei tasti sulla tastiera MouseEventHandler che gestisce i movimenti del mouse Ogni handler è poi associato ad una istanza del tipo EventArgs che costituisce elementi addizionali comunicati insieme alla notifica dell evento. Nei due esempi precedenti sono: KeyEventArgs che comunica il codice ascii del tasto premuto, e la notifica se eventuali tasti funzione sono premuti in contemporanea (SHIFT, ALT, CTRL) MouseEventArgs che comunica quale pulsante del mouse è stato premuto, in quale posizione e quante volte Durante la comunicazione dell evento viene sempre comunicato: l istanza che ha generato l evento gli elementi addizionali (EventArgs) DEFINIZIONE (nella classe che mette a disposizione e genera l evento): Per definire un evento all interno di una classe è sufficiente indicare: accessibilità event tipo_handler nome_evento; DEFINIZIONE (nella classe che riceve la notifica dell evento): La classe utilizzatrice deve dichiarare un metodo che rispetti la tipologia di Handler utilizzata: // asender: istanza che ha eseguito la notifica // aargomenti: elementi addizionali void nome_metodo (object asender, event_args aargomenti) // istruzioni da compiere UTILIZZO (nella classe che mette a disposizione e genera l evento): Per generare l evento sarà sufficiente assicurarsi che vi sia stata associata un azione e di conseguenza richiamare la procedura: if (nome_evento!= null) // this = questa istanza sta notificando l evento // event_args = elementi addizionali Nome_evento(this, event_args); 12

13 UTILIZZO (nella classe che riceve la notifica dell evento): La classe utilizzatrice deve associare una procedura all evento dell istanza da controllare: nome_istanza.nome_evento += new tipo_handler(nome_procedura); Implementiamo l esempio proposto precedentemente dell articolo di magazzino: class Articolo // Dichiarazione dell evento di raggiungimento del livello di riordino public event EventHandler Riordino; // Dichiarazione di un membro dati pubblico con il nome public string Nome; // Dichiarazione di una proprietà Kg (chilogrammi presenti in magazzino) private int VarKg = 1000; public int Kg get return VarKg; set // Impostazione nuovo valore VarKg = value; // Se scende sotto i 100Kg genera l evento di allarme if (VarKg < 100 && Riordino!= null) Riordino(this, new EventArgs()); class Program public static void Main() // Istanzia un oggetto di tipo Articolo Articolo art = new Articolo(); // Associa all evento messo a disposizione da Articolo la procedura Allarme art.riordino += new EventHandler(Allarme); // Modifica Nome art.nome = Banane ; // Modifica la proprietà Kg, indicando un valore inferiore a 100 // provocando la generazione dell evento art.kg = 50; // Metodo chiamato SOLO in caso di notifica dell evento // asender: istanza (oggetto di tipo Articolo) che l ha notificato // aargomenti: argomenti addizionali public static void Allarme(objet asender, EventArgs aargomenti) // Output Console.WriteLine( ATTENZIONE!!! Raggiunto punto di riordino! ); // Dal momento che asender rappresenta un istanza di tipo Articolo // è possibile, tramite un cast, accedere a tutti gli elementi pubblici // dell istanza Console.WriteLine( Articolo: + ((Articolo)aSender).Nome); Console.WriteLine( Quantità: + ((Articolo)aSender).Kg); 13

14 LA PAROLA CHIAVE STATIC L istruzione riservata static consente di dichiarare una classe o un elemento all interno di una classe, visibile e condiviso da tutte le future istanza di quella classe. E possibile dichiarare i seguenti elementi con questo modificatore: classe Permette l utilizzo di tutte le proprietà e i metodi in essa definiti senza la necessità di istanziare un oggetto dello stesso tipo. Utile per riassumere in una classe metodi o proprietà di uso comune, in modo da poterle utilizzare velocemente raggruppate per funzionalità variabili/campi istanza La modifica apportata ad una variabile statica è riflessa su tutte le istanze proprietà La modifica apportata ad una proprietà statica è riflessa su tutte le istanze. Nei costrutti get/set è possibile utilizzare SOLO variabili e metodi a livello classe di tipo STATIC eventi L evento è utilizzabile a livello di classe, e quindi generabile da parte di tutte le istanze Nell implementazione dell evento è possibile utilizzare SOLO variabili e metodi a livello classe di tipo STATIC metodi Il metodo è utilizzabile in qualsiasi momento, da tutte le istanze o dalla classe utilizzatrice (es. il programma) Nell implementazione del metodo è possibile utilizzare SOLO variabili e metodi a livello classe di tipo STATIC DICHIARAZIONE: Per dichiarare un elemento statico è sufficiente far seguire al suo ambito di visibilità la parola STATIC. class Scontrino // Dichiarazione di una proprietà STATICA Aliquota condivisa da tutte le istanze private static int VarAliquota; public static int Aliquota get return VarAliquota; set VarAliquota = value; // Dichiarazione di una proprietà Prezzo private double VarPrezzo; public double Prezzo get return VarPrezzo; set VarPrezzo = value; // Dichiarazione di una proprietà Totale // che restituisce il prezzo ivato public double Totale get return VarPrezzo * (100 + Aliquota) / 100; // Dichiarazione di un metodo STATICO TotaleIvato utilizzabile in qualsiasi momento // che restituisce il prezzo ivato public static double TotaleIvato (double aprezzo) return aprezzo * (100 + Aliquota) / 100; Nell esempio precedente: La proprietà Aliquota deve utilizzare come variabile private una variabile statica, in quanto la proprietà è definita static. 14

15 La proprietà Totale restituirà un valore differente per ciascuna istanza di tipo Scontrino a seconda del valore della proprietà Prezzo. Modificando il valore della proprietà Aliquota si otterrà come conseguenza l applicazione della nuova aliquota iva per tutte le istanze di scontrino. Il metodo TotaleIvato può essere utilizzato in qualsiasi momento per la determinazione dell importo totale di un prezzo qualsiasi applicando l aliquota iva corrente. Il metodo non può usare la proprietà Prezzo in quanto esso è dichiarato static, e può utilizzare al suo interno solo variabili, proprietà o metodi statici della classe. UTILIZZO: Per richiamare un elemento statico di una classe è sufficiente anteporre al nome dell elemento interessato il nome della classe seguita dal punto; come per l utilizzo di una normale proprietà o metodo, ma sostituendo il nome dell istanza con quello della classe. Considerando la classe Scontrino vista sopra, guardiamo il prossimo esempio: class Program // Impostazione dell aliquota da utilizzare Scontrino.Aliquota = 20; // Accesso e modifica della proprietà STATIC // Creazione di una prima istanza Scontrino Scontrino sc1 = new Scontrino(); sc1.prezzo = 100; // Creazione di una seconda istanza Scontrino Scontrino sc2 = new Scontrino(); sc2.prezzo = 1000; // Visualizzazione dell importo totale utilizzando la proprietà Totale // NOTA: viene applicata l aliquota del 20% ad entrambi gli importi, in quanto comune alla classe Console.WriteLine(sc1.Totale); Console.WriteLine(sc2.Totale); // Visualizzazione dell importo totale utilizzando il metodo TotaleIvato // NOTA: viene applicata l aliquota del 20% ad entrambi gli importi, in quanto comune alla classe Console.WriteLine(Scontrino.TotaleIvato(sc1.Prezzo); // Accesso al metodo STATIC Console.WriteLine(Scontrino.TotaleIvato(sc2.Prezzo); // Accesso al metodo STATIC 15

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) 12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP) Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica,

Dettagli

Modulo 4: Ereditarietà, interfacce e clonazione

Modulo 4: Ereditarietà, interfacce e clonazione Modulo 4: Ereditarietà, interfacce e clonazione Argomenti Trattati: Classi, Superclassi e Sottoclassi Ereditarietà Ereditarietà ed Attributi Privati Override super Ereditarietà e Costruttori Polimorfismo

Dettagli

Programmazione II. Lezione 4. Daniele Sgandurra 30/09/2011. daniele.sgandurra@iit.cnr.it

Programmazione II. Lezione 4. Daniele Sgandurra 30/09/2011. daniele.sgandurra@iit.cnr.it Programmazione II Lezione 4 Daniele Sgandurra daniele.sgandurra@iit.cnr.it 30/09/2011 1/46 Programmazione II Lezione 4 30/09/2011 Sommario 1 Esercitazione 2 Panoramica della Programmazione Ad Oggetti 3

Dettagli

Object Oriented Programming

Object Oriented Programming OOP Object Oriented Programming Programmazione orientata agli oggetti La programmazione orientata agli oggetti (Object Oriented Programming) è un paradigma di programmazione Permette di raggruppare in

Dettagli

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti

13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti 13 - Gestione della Memoria nella Programmazione Orientata agli Oggetti Programmazione e analisi di dati Modulo A: Programmazione in Java Paolo Milazzo Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/

Dettagli

CORSO DI PROGRAMMAZIONE

CORSO DI PROGRAMMAZIONE ISTITUTO TECNICO INDUSTRIALE G. M. ANGIOY SASSARI CORSO DI PROGRAMMAZIONE OBJECT ORIENTED PROGRAMMING: I METODI DISPENSA 15.02 15-02_OOP_Metodi_[15] Questa dispensa è rilasciata sotto la licenza Creative

Dettagli

FUNZIONI AVANZATE DI EXCEL

FUNZIONI AVANZATE DI EXCEL FUNZIONI AVANZATE DI EXCEL Inserire una funzione dalla barra dei menu Clicca sulla scheda "Formule" e clicca su "Fx" (Inserisci Funzione). Dalla finestra di dialogo "Inserisci Funzione" clicca sulla categoria

Dettagli

Introduzione a Classi e Oggetti

Introduzione a Classi e Oggetti Introduzione a Classi e Oggetti Oggetto: concetto astratto Entità di un programma dotata di tre proprietà caratteristiche stato informazioni conservate nell oggetto condizionano il comportamento dell oggetto

Dettagli

Informatica. Prof. A. Longheu. Introduzione ai Linguaggi Object-Oriented

Informatica. Prof. A. Longheu. Introduzione ai Linguaggi Object-Oriented Informatica Prof. A. Longheu Introduzione ai Linguaggi Object-Oriented 1 Generalità programmazione OO La programmazione ad oggetti è un particolare modo di scrivere il programma. Si prevede che: 1) si

Dettagli

Java? Sì, grazie. Scopo del corso

Java? Sì, grazie. Scopo del corso Modulo di Java? Sì, grazie Il linguaggio di Internet? Portabilità su qualunque piattaforma (non solo calcolatori): It works everywhere Supporto e disponibilità di strumenti, librerie e documentazione garantiti

Dettagli

1. I database. La schermata di avvio di Access

1. I database. La schermata di avvio di Access 7 Microsoft Access 1. I database Con il termine database (o base di dati) si intende una raccolta organizzata di dati, strutturati in maniera tale che, effettuandovi operazioni di vario tipo (inserimento

Dettagli

Struttura di un programma Java

Struttura di un programma Java Struttura di un programma Java Un programma in Java è un insieme di dichiarazioni di classi. Una classe non può contenere direttamente delle istruzioni, ma può contenere la dichiarazione di metodi, che

Dettagli

PYTHON Inviare dati con i form A cura di Silvio Bonechi [sabandini_at_tiscali_dot_it] per http://www.pctrio.com

PYTHON Inviare dati con i form A cura di Silvio Bonechi [sabandini_at_tiscali_dot_it] per http://www.pctrio.com PYTHON Inviare dati con i form A cura di Silvio Bonechi [sabandini_at_tiscali_dot_it] per http://www.pctrio.com 10.07.2006 Ver. 1.0 In questo articolo vedremo come gestire con un FORM l invio di dati ad

Dettagli

Corso su LINQ Lezione 16. Introduzione

Corso su LINQ Lezione 16. Introduzione LINQ to SQL Introduzione Con questa lezione introduciamo il flavor LINQ to SQL. Dopo aver visto quindi tutte le funzionalità e gli operatori di LINQ to Object, affronteremo ora la tematica riguardante

Dettagli

JAVASCRIPT. Tale file è associato alla pagina web mediante il tag