sabato 24 gennaio 2009

La programmazione orientata a oggetti

Introduzione


In questo capitolo, verrà discusso un argomento molto importante che è la base per la programmazione con la tecnologia .Net. In particolare si vedrà la programmazione a oggetti, la creazione di classi ed altre metodologie, per un approfondimento dell’argomento si rimanda ad altri libri specializzati in tale materia. In questo capitolo verranno fornite le basi per tale argomento evidenziando le varie tecniche.


Il programmatore nei suoi progetti, può definirsi delle classi, che poi verranno utilizzate (l’istanza di una classe si definisce oggetto) nei vari progetti o attività, o ampliate. Le classi hanno proprietà, metodi, campi ed eventi.



I campi, come anche le proprietà, rappresentano le informazioni contenute nella classe, I campi sono simili alle variabili in quanto i loro valori possono essere letti ed impostati direttamente.



Il metodo è una funzione o procedura che esegue determinate operazioni, ossia eseguendo un determinato metodo la classe esegue delle istruzioni di codice, eventualmente basandosi anche sui valori delle proprietà. Per esempio, il metodo show, della classe form, permette di visualizzare l’oggetto Form che si vuole caricare in memoria. In questo caso il metodo non accetta argomenti. I metodi possono avere eventualmente anche dei parametri e possono restituire dei valori,.



Figura 4.2 – La finestra delle proprietà del progetto, in cui si vede la casella “Spazio dei nomi di primo livello” valorizzata



4.4 Le classi.


Dopo aver fatto una panoramica sulla programmazione ad oggetti, vediamo come si crea una classe e tutte le varianti. In un file, possiamo avere una o più classi, che possono situarsi in uno o più namespace, in .net la classe è definita tramite la parola chiave class , il blocco di tale classe è formato da class nomeclasse e chiuso da end class per VB.Net mentre per C# dalla parola chiave Class nome classe e delimitata da una parentesi graffa aperta e da una chiusa. All’interno di questo blocco, si creano le varie proprietà, campi, metodi ed eventi.


Di seguito si riporta la sintassi per i linguaggi Vb.net e C#



Vb.Net


Class Persona



End Class


C#



class Persona


{



}



Come si vede, in vb.net la definizione di classe è racchiusa tra la parola class seguita da un nome che la contraddistingue e le parole chiavi end class. Mentre in C# dalla parola chiave class racchiusa tra una parentesi graffa aperta ed un'altra chiusa. All’interno di tali dichiarazione dobbiamo scrivere il codice della nostra classe.


Le classi possono essere di tipo public o private, la differenza sta nella visibilità nel progetto. Infatti dichiarando una classe di tipo public (pubblica) possiamo utilizzarla in altre classi del progetto, mentre privata ha una visibilità all’interno del modulo di classe. Stessa cosa anche per le variabili o costanti, se sono di tipo private, non si possono accedere al di fuori della medesima classe.


Di seguito si riporta un esempio di codice:


Vb.Net


Public Class Persona


'questa variabie non è accessibile al di fuori della classe


Private Nome As String


'questa è visibile anche fuori dalla classe


Public Cognome As String


End Class



C#


class Persona


{


//questa variabie non è accessibile al di fuori della classe


private string Nome;


//questa è visibile anche fuori dalla classe


public string Cognome;



}



Quando una classe viene instanziata prende il nome oggetto, per dichiarare un oggetto occorre utilizzare la parola chiave new, in visual basic net, occorre utilizzare la parola chiave dim nome oggetto as new nomeClasse mentre in C#, nomeClasse nomeoggetto = new nomeClasse.


Di seguito si riporta un esempio di codice.


VB.Net


'creo un oggetto della classe persona


Dim ObjPersona As New Persona


C#


//Creo un oggetto della classe persona


Persona ObjPersona = new Persona();




Inoltre si può dichiarare una classe ed instanziarla in un secondo momento, senza l’utilizzo della parola new, come riportato nell’esempio seguente:


VB.Net


'creo l'oggetto


Dim ObjPersona As Persona


'Instanza dell'oggetto


ObjPersona = New Persona()




C#


//creo l'oggetto


Persona objpersona;


//lo instanzio.


objpersona = new Persona();




I livelli di accessibilità permettono di accedere alla classe o ai suoi membri con adeguate restrizioni, i livelli di accessibilità sono i seguenti.



VB.Net


Public: Nessuna restrizione di accesso, accessibili da qualsiasi parte del codice.


Protected: l'accesso è limitato alla classe di appartenenza o ai tipi derivati dalla classe di appartenenza.


Friend; L’accesso è limitato al progetto corrente.


Protected Friend: L’accesso è limitato al progetto corrente o dalle classi derivate.


Private: L’accesso è limitato al modulo, classe o struttura di appartenenza, valore predefinito di tutti i membri della classe.



C#


Public : nessuna restrizione di accesso, accessibile da qualsiasi parte del codice.


Protected: l'accesso è limitato alla classe di appartenenza o ai tipi derivati dalla classe di appartenenza


Internal: l'accesso è limitato al progetto corrente


Protected Internal: l'accesso è limitato al progetto corrente o ai tipi derivati dalla classe di appartenenza


Private: l'accesso è limitato al tipo di appartenenza. Valore predefinito per i membri e metodi.



A seconda del contesto in cui si effettua la dichiarazione di un membro, sono consentiti solo determinati livelli di accessibilità dichiarata. Se nella dichiarazione di un membro non è stato specificato alcun modificatore di accesso, verrà utilizzato un valore di accessibilità predefinito, per le classi il valore di default è private(C#) e public (VB.Net), nel caso che non si trovino dichiarati nel primo livello, in tal caso è consentito solo l’accessibilità di livello public (default) o internal(C#) o friend(VB.net).


Come si è visto nel precedente frammento di codice, la variabile dichiarata come private, non sarà accessibile all’esterno della classe, mentre quella dichiarata come public è accessibile dall’esterno.



4.5. I Campi:


I campi sono oggetti o valori che si trovano o nelle classi o nelle strutture. Consentono di gestire i dati all’interno della classe o struttura, possono essere o di tipo pubblico (public) o privato (private) o protected (protetto) o internal (interno).


Nell’esempio precedente, la classe persona dispone di due campi, uno di tipo private ( Nome) e l’altro di tipo pubblico (Cognome), in questo modo è visibile solo quello pubblico.


Vb.Net


Public Class Persona


'questa variabie non è accessibile al di fuori della classe


Private Nome As String


'questa è visibile anche fuori dalla classe


Public Cognome As String


End Class



C#


class Persona


{


//questa variabie non è accessibile al di fuori della classe


private string Nome;


//questa è visibile anche fuori dalla classe


public string Cognome;



}


4.6 I Metodi:


I metodi permettono l’azione che l’oggetto può eseguire, e possono restituire dei valori oppure possono essere richiamati tramite argomenti, i metodi possono avere particolari tipologie, che esamineremo qui di seguito. I metodo possono essere funzioni se restituiscono un valore oppure delle procedure. Per la creazione di metodi per VB.net, l’accesso se non viene espresso di default è di tipo pubblico (public ) mentre in C# è privato (private). La chiamata di un metodo su un oggetto è simile all'accesso a un campo o proprietà. Dopo il nome dell'oggetto è necessario aggiungere un punto, il nome del metodo e le parentesi. Gli argomenti sono riportati tra parentesi e separati da virgole.



Di seguito si riportano i vari esempi di codice riguardante la creazione dei metodi.



Creazione di un metodo che visualizza un messaggio.



VB.Net


Class Persona


'questa variabie non è accessibile al di fuori della classe


Private Nome As String


'questa è visibile anche fuori dalla classe


Public Cognome As String



'metodo che visualizza un messaggio


Public Sub Visualizza()


'visualizza a video il valore del campo cognome


MessageBox.Show(Cognome)


End Sub



End Class



Nella form la richiamo in questo modo:


'creo un oggetto della classe persona


Dim ObjPersona As New Persona


'imposto il valore del campo cognome


ObjPersona.Cognome = "Mattei"


'eseguo il metodo della classe


ObjPersona.Visualizza()



C#


class Persona


{


//questa variabie non è accessibile al di fuori della classe


private string Nome;


//questa è visibile anche fuori dalla classe


public string Cognome;


//metodo che visualizza un messaggio


public void Visualizza()


{


//visualizza a video il valore del campo cognome


MessageBox.Show( Cognome);


}





}



Nella form la richiamo nel seguente modo:


//creo un oggetto della classe persona


Persona ObjPersona = new Persona();


//imposto il valore del campo cognome


ObjPersona.Cognome = "Mattei";


//eseguo il metodo della classe


ObjPersona.Visualizza();




Di seguito si riporta un esempio di un metodo che accetta un valore (data di nascita ) e restituisce un valore (anni), in questo caso


VB.Net


Class Persona


'questa variabie non è accessibile al di fuori della classe


Private Nome As String


'questa è visibile anche fuori dalla classe


Public Cognome As String



'metodo che visualizza un messaggio


Public Sub Visualizza()


'visualizza a video il valore del campo cognome


MessageBox.Show(Cognome)


End Sub


'metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


Public Function Anni(ByVal DataNascita As DateTime) As Integer



Return DateTime.Now.Year - DataNascita.Year



End Function



End Class



Nella form la richiamo nel seguente modo.


Dim ObjPersona As New Persona


'imposto una data da passare


Dim DttNascita As New DateTime(1974, 12, 31)


'ritorna il numero degli anni (la differenza


Dim intAnni As Integer = ObjPersona.Anni(DttNascita)


'visualizzo a video il risultato


MessageBox.Show(intAnni.ToString())






C#



class Persona


{


//questa variabie non è accessibile al di fuori della classe


private string Nome;


//questa è visibile anche fuori dalla classe


public string Cognome;


//metodo che visualizza un messaggio


public void Visualizza()


{


//visualizza a video il valore del campo cognome


MessageBox.Show( Cognome);


}


//metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


public int Anni(DateTime DataNascita)


{



return DateTime.Now.Year - DataNascita.Year;



}




}





Nella form la richiamo nel seguente modo:


//creo un oggetto della classe persona


Persona ObjPersona = new Persona();


//imposto una data da passare


DateTime DttNascita = new DateTime(1974, 12, 31);


//ritorna il numero degli anni (la differenza


int anni = ObjPersona.Anni(DttNascita);


//visualizzo a video il risultato


MessageBox.Show(anni.ToString());









Overloads di un metodo.


Tramite la parola chiave overloads (VB.Net), possiamo creare metodi o proprietà con lo stesso nome ma con un numero di parametri diversi o con tipi di parametri diversi. Il modificatore Overloads, si può applicare a procedure, funzioni , proprietà ed all’istruzione operator.


Nei metodi la parola chiave overloads, può tornare utile nel caso che abbiamo metodi con lo stesso nome, ma con parametri di diverso tipo o numero di parametri diversi. Quando andiamo ad eseguire il metodo, nell’intellisense verrà indicato quale metodo utilizzare con quali parametri. La parola chiave overloads può essere omessa in tutti i metodi in VB.Net mentre in C# non occorre utilizzare tale parola chiave, ma solo il nome del metodo o proprietà. La tecnologia Intellisense è in grado di riconoscere correttamente i metodi overloads e mostra un elenco di tutte le forme sintattiche possibile, nel quale è possibile navigare utilizzando i tasti di direzione (alto e basso) e quelli riportati nella descrizione. Questa tecnica fa parte di un elemento della programmazione ad oggetti ossia al polimorfismo, ossia quello di avere un metodo con diverse firme (parametri o tipi di parametri). Di seguito si riporta un esempio del metodo visualizza visto nel precedente esempio.



VB.Net


'metodo che visualizza un messaggio, cambiato con la parola overloads


Public Overloads Sub Visualizza()


'visualizza a video il valore del campo cognome


MessageBox.Show(Cognome)


End Sub


'overload del metodo visualizza


Public Overloads Sub Visualizza(ByVal nome As String)


'visualizzo un messaggio a video con il valore che viene passato


MessageBox.Show(nome & " " & Cognome)


End Sub


'overload del metodo visualizza con un diverso tipo


Public Overloads Sub Visualizza(ByVal sesso As Boolean)


'visualizzo un messaggio a video


If sesso = True Then


MessageBox.Show("Uomo" & " " & Cognome)


Else


MessageBox.Show("Donna" & " " & Cognome)


End If



End Sub


'overload del metodo visualizza con più paramatri


Public Overloads Sub Visualizza(ByVal nome As String, ByVal sesso As Boolean)


'visualizzo un messaggio a video


If sesso = True Then


MessageBox.Show("Uomo" & " " & nome & Cognome)


Else


MessageBox.Show("Donna" & " " & nome & Cognome)


End If



End Sub




Di seguito viene riporta un esempio per richiamare tale metodo.


'creo un oggetto della classe persona


Dim ObjPersona As New Persona


'imposto il valore del campo cognome


ObjPersona.Cognome = "Mattei"


'eseguo il metodo della classe


ObjPersona.Visualizza()


'eseguo il metodo visualizza passandogli un valore


ObjPersona.Visualizza("Emanuele")


'eseguo il metodo visualizza passando un valore booleano


ObjPersona.Visualizza(True)


'eseguo il metodo visualizza passando due valori


ObjPersona.Visualizza("Emanuele", True)



C#


//metodo che visualizza un messaggio


public void Visualizza()


{


//visualizza a video il valore del campo cognome


MessageBox.Show( Cognome);


}


//overload del metodo visualizza


public void Visualizza(string nome)


{


MessageBox.Show(nome + " " + Cognome);


}


//overload del metodo visualizza con un diverso tipo


public void Visualizza(bool sesso)


{


if (sesso == true)


{


MessageBox.Show("Uomo" + " " + Cognome);



}


else


{


MessageBox.Show("Donna" + " " + Cognome);



}


}



//overload del metodo visualizza con più paramatri


public void Visualizza(string nome, bool sesso)


{


if (sesso == true)


{


MessageBox.Show("Uomo" + " " + nome + Cognome);



}


else


{


MessageBox.Show("Donna" + " " + nome + Cognome);



}



}



Le proprietà rappresentano le informazioni che una classe può avere. Le proprietà possono restituire o ricevere valori, quando si vuole ottenere il valore di una proprietà, viene eseguito nella classe il metodo get, di quella proprietà, mentre per impostarlo si utilizza set. A differenza dei campi, tramite i metodi get e set, si ha un maggiore controllo sulle modalità di impostazione e restituzione dei valori. Le proprietà possono essere anche di sola lettura, ossia il valore non si può cambiare. Le proprietà hanno il compito di ricevere o restituire un valore di una determinata classe. Per esempio la classe form, ha una proprietà, denominata Text, la quale restituisce o imposta il testo che viene visualizzata nella barra del titolo.



Gli eventi, sono delle azioni che la classe restituisce, a differenza dei metodi, in cui viene o vengono eseguite determinate azioni, l’evento notifica agli altri oggetti che la classe sta eseguendo una determinata fase.


Per esempio, nella classe form, l’evento load, è quella situazione in cui la classe è in fase di caricamento, di solito il programmatore in questo evento scrive il codice, per eseguire delle operazioni durante la fase di caricamento della form, per esempio per eseguire un caricamento dei dati da visualizzare a video.



Nella programmazione ad oggetti, ci sono delle regole da tenere sempre presente, quale l’ereditarietà, il poliformismo e l’ incapsulamento


Con la tecnologia .Net si fa uso delle classi, basti pensare che gli oggetti e le funzioni che si utilizzano nei nostri progetti, sono tutte classi offerte dal Compact Framework.


Con la classe si rappresenta in modo astratto qualcosa di reale, si cerca di rappresentare il mondo reale, o meglio, si creano determinate classi che devono rappresentare il più possibile gli oggetti che vogliamo rappresentare. Questi oggetti possono essere riutilizzati nel progetto o nei vari progetti. Una classe può essere ereditata, ossia si può creare una classe che eredita metodi, eventi e proprietà di una classe già esistente ma con altre funzionalità. Per esempio, si può creare una classe denominata animale, la quale ha delle sotto classi, divise per carnivori o vegetariani, a loro volta possono essere ereditati da altre classi ecc.


La classe principale, è detta super classe o classe madre o classe base; quelle derivate sono classi secondarie, Nella programmazione a oggetti con la terminologia ereditarietà si fa presente che una classe può essere ereditata da un'altra, e quindi (avere proprietà, metodi ed eventi) il vantaggio di una classe ereditaria è quella di non riscrivere tutto il codice, ma riutilizzare (metodi, proprietà ed eventi) quello già presente nella classe superiore, inoltre modificando la classe principale, tutte le modifiche verranno acquisite a tutte le sottoclassi ereditate.



Poliformismo


Con questo termine si indica quella tecnica di utilizzare in più classi lo stesso nome di una proprietà o metodo in diverse classi anche se in ognuna di esse sono implementati in modo diverso, in pratica possiamo avere diverse classi che hanno una funzione o proprietà con lo stesso nome. Per esempio, per la classe veicolo possiamo avere un metodo chiamato alimentazione, il quale metodo varia a secondo del veicolo, se abbiamo una classe denominata motorino, può essere completamente diverso dal metodo con lo stesso nome definito nella classe base.



Ereditarietà


Si possono creare delle classi che ereditano da una classe superiore, ossia: supponiamo di avere una classe la quale espone dei metodi, proprietà ed eventi, anziché scrivere una nuova classe con tali funzionalità, possiamo creare una classe che erediti da quella, ed eventualmente aggiungere alla nuova classe altre proprietà, metodi o eventi. Per esempio se abbiamo una classe persona, possiamo creare una classe bambino che eredita dalla classe persona, alcune proprietà e metodi, come per esempio la proprietà nome, cognome ed il metodo parlare.



Incapsulamento


Questa tecnica permette di considerare in un singolo oggetto un raggruppamento delle proprietà, metodi ed altri membri. Nella programmazione a oggetti si raggruppano i dati e le funzioni per manipolarli nelle classi, in questo modo non occorre conoscere il codice, ma solo ciò che viene esposto.


Un esempio nella vita privata di ognuno di noi, può essere l’utilizzo di un automobile, chiunque sa utilizzare una macchina, sa che per azionarla occorre girare la chiave (in programmazione può essere considerata un metodo avvio) , inoltre accensione fari, tergicristallo e così via, possono considerarsi altri metodi. In questo modo non occorre conoscere il funzionamento e i vari meccanismi che servono al funzionamento di tali attività, ma solo che tramite determinati pulsanti o chiavi possiamo azionare o spegnere un determinato comando.



4.2 I Moduli



In Visual basic net abbiamo i moduli, il loro compito è quello di contenere funzioni e variabili che possiamo utilizzare nel nostro progetto. Anche i moduli, come le classi hanno un costruttore, in fatti inserendo la dicitura New, si crea un costruttore all’interno del modulo.


Viene invocata solo quando viene referenziata per la prima volta una variabile o una procedura, se invece si accede ad una costante definita nel modulo questa, il costruttore non viene eseguito.


Per inserire un modulo in un progetto VB.net, occorre fare con il tasto destro sul nome del progetto, aggiungi->modulo, oppure tramite la voce di menu, progetto->aggiungi nuovo elemento e selezionare nella finestra che viene aperta la voce modulo.


La sintassi del modulo è la seguente


Module NomeModulo



End Module



Se nel modulo, inseriamo la procedura denominata sub main, possiamo impostare l’avvio del progetto da quella funzione.


Di seguito si riporta la figura che indica come impostare dalle proprietà del progetto, si imposti il nome della funzione sub main, per avviare il progetto da quella funzione.



Figura 4.1


4.3 I namespace.


I namespace o spazio dei nomi, hanno una grande importanza; infatti, il loro compito che è quello di raggruppare un insieme di classi, serve anche ad evitare ambiguità tra le classi.Iin questo modo si possono creare tipi univoci globali. In un file .vb o .cs possiamo avere uno o più spazi di nomi .E’ da ricordare che si possono avere namespace annidati ossia uno dopo l’altro. Di seguito si riporta la sintassi per la creazione di uno spazio dei nomi



Vb,net


Namespace Classi



End Namespace



C#



namespace Classi


{



}




Dopo aver creato in un nostro file, un determinato spazio dei nomi, per richiamo nel progetto, dobbiamo utilizzare la parola chiave imports seguita dal nome del namespace, per vb.net e using seguita dal nome del namespace, per C#.


Di seguito si riporta un frammento di codice per importare nel nostro progetto uno spazio di nomi, in questo modo potremmo utilizzare le classi che ne fanno parte.


Vb.net


'importo il namespace nel progetto


Imports DeviceClassiVb.Classi


C#


//importo il namespace nel progetto


using Classi;



Da notare in VB.Net è che lo spazio dei nomi di primo livello, viene assegnato con il nome del progetto. Come si è visto nell’esempio precedente, per utilizzare lo spazio dei nomi Classi, si è dovuto inserire prima il nome del progetto (DeviceClassiVb.Classi ) e poi il nome del namespace creato precedentemente, altrimenti non è visibile lo spazio dei nomi, per evitare ciò, il nome dello spazio dei nomi di primo livello, dev’essere impostato con un valore null (vuoto) nella casella “spazio dei nomi di primo livello” che si trova nelle proprietà del progetto ( proprietà Progetto->applicazione->casella di testo indicante la voce “Spazio dei nomi di primo livello:”.


Di seguito si riporta un esempio per richiamare tale metodo



//eseguo il metodo della classe


ObjPersona.Visualizza();


//eseguo il metodo visualizza passando un valore booleano


ObjPersona.Visualizza(true);


//eseguo il metodo visualizza passandogli un valore


ObjPersona.Visualizza("Emanuele");


//eseguo il metodo visualizza passando due valori


ObjPersona.Visualizza("Emanuele", true);



Figura 4.3 – la lista dei vari overloads mostrata dall’Intellisense


Membri condivisi


Un dato membro statico è un dato che verrà condiviso da tutte le istanze della classe, la sua esistenza non è dunque collegata ad un oggetto in particolare, le classi statiche e i relativi membri vengono utilizzati per creare dati e funzioni a cui sia possibile accedere senza creare un'istanza della classe. In C# si utilizza la parola chiave static, mentre in VB.Net tramite la parola chiave Shared. Questi possono essere metodi, proprietà, campi ed eventi. Mentre l'istanza di una classe contiene una copia distinta di tutti i campi di istanza della classe, esiste una sola copia per ciascun campo Shared (VB.Net) o static (C#).


Di seguito si riporta un esempio di codice in pratica nella nostra classe è stato dichiarato un metodo di tipo static, il quale viene utilizzato per visualizzare un messaggio a video, ed un campo che contiene il valore stringa, quest’ultimo verrà modificato il valore, in entrambi i casi non si crea un istanza della classe.


VB.Net


Definizione di classe


'classe che espone un campo ed un metodo shared


Class bambino


Event Mangiare(ByVal Cibo As String)


'campo condiviso


Public Shared Nome As String



Sub Mangia()


'viene eseguito l'evento


RaiseEvent Mangiare("frutta")


'eventuale codice


End Sub



Sub beve()


'viene eseguito l'evento


RaiseEvent Mangiare("Beve")


'eventuale codice


End Sub


'metodo condiviso


Shared Sub Visualizza()


MessageBox.Show("Messaggio a video")


End Sub



End Class



Esempio di codice utilizzato in una form.



'utilizzo il metodo shared senza istanziare la classe


bambino.Visualizza()


'imposto il valore del campo di tipo shared


bambino.Nome = "Emanuele"


'modifico il valore del campo di tipo shared


bambino.Nome = bambino.Nome & " " & "Mattei"


'visualizzo il valore del campo di tipo shared


MessageBox.Show(bambino.Nome)




C#



Classe:


//classe che espone un campo ed un metodo shared


class Bambino


{


//implemento il delegato per l'evento


public event EventoMangiare Mangiare;



//variabile di tipo static non occorre creare un istanza della classe


public static string Nome;



public void Mangia()


{


//viene eseguito l’evento


if (Mangiare != null)


{


//scateno l'evento


Mangiare("Frutta");


//eventuale codice


}



}


//viene eseguito l’evento


public void Beve()


{


if (Mangiare != null)


{


//scateno l'evento


Mangiare("Beve");


//eventuale altro codice


}


}


//metodo di tipo static non occorre creare un istanza della classe


public static void Visualizza()


{


MessageBox.Show("Messaggio a video");



}




}



Richiamata nella form:


//utilizzo il metodo messaggio senza creare un instanza della classe altrimenti non è visibile


Persona.Messaggio();











4.7 Le proprietà


Con le proprietà, possiamo gestire le informazioni nella nostra classe, ed eventualmente manipolare tali dati. Nelle proprietà possiamo utilizzare le funzioni di tipo get per rilevare un valore, set per impostare un valore oppure entrambi. Con la parola chiave value, viene utilizzata per definire il valore assegnato dall'indicizzatore set. Per default le proprietà sono di tipo pubblic, si può modificare il livello di accesso di una proprietà mediante un modificatore di accesso sull'istruzione property(VB.Net) o tipo (C#). Le proprietà che hanno solo la funzione di tipo get, sono proprietà di sola lettura; mentre quelle con la sola funzione set, sono proprietà di sola scrittura. Per la funzione get, si deve terminare con la parola chiave return, di solito seguito da una variabile membro, mentre per la funzione set, un parametro implicito denominato value, il cui tipo corrisponde al tipo della proprietà si imposta il valore della proprietà.


Di seguito si riporta un esempio di codice ed il suo utilizzo.



VB.Net


Sintassi:


Property Nome (parametri) as tipo


Get


---codice


End get


Set (byval value as tipo)



End set


Class persona


'variabile della proprietà nazionalità


Private m_Nazionalita As String



'proprietà che identifica la nazionalità


Property nazionalita() As String


Get


'restituisce il valore


Return m_Nazionalita


End Get


Set(ByVal value As String)


'imposta il valore


m_Nazionalita = value


End Set


End Property


End Class




Esempio di utilizzo nella form


Dim ObjPersona As New Persona()


'imposto la proprietà


ObjPersona.nazionalita = "Italiana"


'Visualizzo il valore della proprietà


MessageBox.Show(ObjPersona.nazionalita)





C#


Sintassi


Tipo nome


{


Get


{


---codice


}


Set


{


---codice = value


}


}



class Persona


{


//variabile della proprietà nazionalità


private string mNazionalita;



//proprietà che identifica la nazionalità.


public string Nazionalita


{


get


{


//restituisco il valore della proprietà


return mNazionalita;



}


set


{


//imposto il valore della proprietà


mNazionalita = value;


}



}


}





Esempio di utilizzo nella form



Persona objPersona = new Persona();


//imposto il valore della proprietà


objPersona.Nazionalita = "Italiana";


//Visualizzo il valore della proprietà


MessageBox.Show(objPersona.Nazionalita);




Nelle proprietà possiamo concatenare, aggiungere ed altro ancora i valori della proprietà, riprendendo l’esempio precedente, qui di seguito si riporta un esempio in cui si aggiunge del testo alla proprietà nazionalita.


VB.Net


'concateno il valore della proprietà nazionalita


ObjPersona.nazionalita &= " e Francese"


C#


//concateno il valore della proprietà nazionalita


objPersona.Nazionalita += " e Francese";



Proprietà di sola lettura o di sola scrittura.


Le proprietà possono essere o di sola lettura (get) oppure di sola scrittura (set) , in VB.Net per definire una proprietà di sola lettura occorre utilizzare la parola chiave readyonly , mentre in C# occorre scrivere solo la funzione get, mentre per le proprietà di sola scrittura, in VB.Net precedere la parola chiave property con la parola chiave writeonly, mentre in C# omettere la funzione get.


Di seguito si riporta un esempio di codice.



VB.Net


Sintassi


Solo lettura:


readonly property Nome() as tipo


get


return valore


end get


end property


'variabile per la proprietà occhiali


Dim mOcchiali As String = "No"


'proprietà di sola lettura


ReadOnly Property Occhiali() As String


Get


Return mOcchiali


End Get



End Property


Sintassi:


Solo scrittura:


writeonly property as tipo


set (byval value as tipo)


codice = value


end set


end property



'variabile per la proprietà fumatore


Dim mFumatore As Boolean


'proprietà di sola scrittura


WriteOnly Property Fumatore() As Boolean


Set(ByVal value As Boolean)


mFumatore = value


End Set


End Property



Esempio di utilizzo della proprietà, nella form



Dim ObjPersona As New Persona()


'visualizzo la proprietà di sola lettura


MessageBox.Show(ObjPersona.Occhiali)


'imposto la proprietà di sola scritrua


ObjPersona.Fumatore = True



C#


Sintassi


Solo lettura:


Tipo nome


{


Get


{



-codice


}


}



class Persona


{



//variabile per la proprietà occhiali


string mOcchiali = "No";


//proprietà occhiali di sola lettura


public string Occhiali


{


get


{


return mOcchiali;


}



}


}


Sintassi:


Solo scrittura:


tipo nome


{


set


{



-codice = value;


}


}



//variabile per la proprietà fumatore


bool mFumatore;


//proprietà di sola scrittura


public bool Fumatore


{



set


{


mFumatore = value;


}



}




Esempio di utilizzo della proprietà, nella form




Persona objPersona = new Persona();


//utilizzo della prorpietà di sola lettura


MessageBox.Show(objPersona.Occhiali );


//utilizzo della prorpietà di sola scrittura


objPersona.Fumatore = false ;





Nel caso che si voglia impostare un valore in una proprietà di sola lettura o rilevare il valore di una proprietà di sola scrittura, si viene avvisati dall’ambiente di sviluppo tramite messaggi di errore, in fase di compilazione.


Nelle proprietà possiamo sollevare un’ eccezione, se- qualora il valore che si vuole impostare non è corretto- tramite la parola chiave throw possiamo sollevare un eccezione. Di seguito si riporta un esempio di codice, di una proprietà (chiamata sesso) che accetta come valore “uomo” o “donna”, nel caso venga impostato un valore diverso, viene sollevata un eccezione.


VB.Net



Class Persona


'variabile per la proprietà sesso


Dim m_sesso As String


'Proprietà che controlla il valore se è uomo o donna


Public Property sesso() As String


Get


Return m_sesso


End Get


Set(ByVal value As String)


'verifico che il dato inserito sia corretto


If value.ToLower = "uomo" Or value.ToLower = "donna" Then


m_sesso = value


Else


'sollevo un eccezione con un messaggio


Throw New Exception("Inserire uno dei seguenti valori uomo o donna")


End If




End Set


End Property


End Class



Esempio di utilizzo della classe nella form.



Try




Dim ObjPersona As New Persona()


'imposto il valore della proprietà viene sollevata un eccezione


ObjPersona.sesso = "M"


Catch ex As Exception


MessageBox.Show(ex.Message)


End Try




C#


class Persona


{


//variabile per la proprietà sesso


string mSesso;


//Proprietà che controlla il valore se è uomo o donna


public string sesso


{


get


{



return mSesso;


}


set



{


//verifico che il dato inserito sia corretto


if ((value.ToLower() =="uomo") (value.ToLower()=="donna"))


{


mSesso = value ;


}


else


{


//sollevo un eccezione con un messaggio


throw new Exception("Inserire uno dei seguenti valori uomo o donna");


}



}



}



}



Esempio di utilizzo della classe nella form




try


{


Persona objPersona = new Persona();


//imposto il valore della proprietà viene sollevata un eccezione


objPersona.sesso = "M";


}


catch (Exception ex)


{


MessageBox.Show(ex.Message);



}







4.8 I costruttori:


Il costruttore è un metodo che svolge un ruolo particolare, ovvero permette la creazione di un oggetto, viene eseguito ad ogni nuova creazione di un’istanza di classe. Il costruttore può accettare argomenti e non restituisce valori, in esso si scrive il codice per inizializzare l’oggetto ed eventualmente impostare dei valori dei membri della classe . In VB.Net il costruttore si dichiara tramite la parola chiave sub new, mentre in C# hanno lo stesso nome della classe. Nella dichiarazione di un oggetto, tramite la parola chiave new, viene creata l’istanza dell’oggetto. Di seguito si riporta un esempio di codice


VB.Net


Sintassi


Class nome



Sub new


---codice


End sub



End class



Class Ragazzo


Public Avviata As Boolean


Sub New()


'inizializzo la variabile


Avviata = True


'eventuale codice per altre inizializzazioni



End Sub


End Class





Esempio di codice per istanziare l’oggetto


'creo un oggetto della classe ragazzo


Dim ObjRagazzo As New Ragazzo()


'visualizzo a video il valore del campo della classe


MessageBox.Show(ObjRagazzo.Avviata)





C#


Sintassi


Class Nome


{


Public NomeClasse


{



}



}



class Ragazzo


{


public bool Avviata;


public Ragazzo()


{


//inizializzo la variabile


Avviata = true ;


//eventuale codice per altre inizializzazioni



}



}






Esempio di codice per istanziare l’oggetto


//creo un oggetto dalla classe ragazzo


Ragazzo ObjRagazzo = new Ragazzo();


//visualizzo a video il valore del campo della classe


MessageBox.Show(ObjRagazzo.Avviata.ToString());




Costruttore con più parametri e firme.


I costruttori possono accettare argomenti, inoltre è possibile avere più costruttori tramite la tecnica del overloads, a differenza dei metodi, i costruttori non accettano la parola chiave overloads.


L’esempio seguente mostra un costruttore con argomenti


VB.Net


Class Ragazzo


'variabile pubblica che visualizza il valore imposto nel costruttore


Public Nome As String


'un costruttore che accetta i parametri


Sub New(ByVal NomePersona As String)


'imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona


End Sub


End Class



Esempio di utilizzo.


'creo l'oggetto di tipo ragazzo passando un valore al costruttore


Dim ObjRagazzo As New Ragazzo("Emanuele")


'visualizzo a video il valore della variabile nome


MessageBox.Show(ObjRagazzo.Nome)




C#


class Ragazzo


{


//variabile pubblica che visualizza il valore imposto nel costruttore


public string Nome;



//il costruttore che accetta un parametro


public Ragazzo(string NomePersona)


{


//imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona;




}



}



Esempio di utilizzo.


//creo l'oggetto di tipo ragazzo passando un valore al costruttore


Ragazzo ObjRagazzo = new Ragazzo("Emanuele");


//visualizzo a video il valore della variabile nome


MessageBox.Show(ObjRagazzo.Nome);



Anche il costruttore, essendo un metodo supporta la tecnica del overloads, di seguito riportiamo un esempio



VB.Net


Class Ragazzo


Public Avviata As Boolean


'variabile pubblica che visualizza il valore imposto nel costruttore


Public Nome As String


'costruttore


Sub New()


Avviata = True


End Sub



'un costruttore che accetta un parametro


Sub New(ByVal NomePersona As String)


'imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona


End Sub


'costruttore che accetta più parametri


Sub New(ByVal NomePersona As String, ByVal CognomePersona As String)


Nome = NomePersona & " " & CognomePersona


End Sub


End Class




C#


class Ragazzo


{


public bool Avviata;


//variabile pubblica che visualizza il valore imposto nel costruttore


public string Nome;


//Costruttore


public Ragazzo()


{


Avviata = true;


}



//il costruttore che accetta un parametro


public Ragazzo(string NomePersona)


{


//imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona;




}


//costruttore che accetta più parametri


public Ragazzo(string NomePersona, string CognomePersona)


{


Nome = NomePersona + " " + CognomePersona;


}



}





Finalize e distruttore.


Quando si crea un oggetto, l’applicazione tenta di allocare memoria per il nuovo oggetto e se nel caso non ha sufficiente memoria, la libera libera. Il Compact Framework lancia un processo di garbage collection, il quale identifica gli oggetti non più utilizzati e libera la memoria.


Il distruttore Finalize è un metodo protetto che può essere chiamato solo dalla classe a cui appartiene o dalle classi derivate. Poiché Finalize viene chiamato automaticamente dal sistema quando viene eliminato in modo permanente un oggetto, si consiglia di non chiamarlo in modo esplicito dall'esterno dell'implementazione Finalize di una classe derivata.


Un distruttore Finalize non deve generare eccezioni, perché queste non possono essere gestite dall'applicazione e possono provocarne l'interruzione.



VB.Net


Class Ragazzo


Public Avviata As Boolean


'variabile pubblica che visualizza il valore imposto nel costruttore


Public Nome As String


'costruttore


Sub New()


Avviata = True


End Sub



'un costruttore che accetta un parametro


Sub New(ByVal NomePersona As String)


'imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona


End Sub


'costruttore che accetta più parametri


Sub New(ByVal NomePersona As String, ByVal CognomePersona As String)


Nome = NomePersona & " " & CognomePersona


End Sub


'utilizzo del metodo finalize, verrà visualizzato il messaggio nella finestra debug al termine dell'applicazione


Protected Overrides Sub Finalize()


Debug.WriteLine("Oggetto distrutto")


End Sub


End Class



Se nel caso si voglia disporre nella nostra classe di un distruttore, possiamo dare la possibilità di liberare la memoria, utilizzando il metodo Dispose dell’interfaccia IDisposable.


La nostra class sarà implementata con l’interfaccia IDisposable.



VB.Net



Class Ragazzo


Implements IDisposable


'variabile che indica se l'oggetto è stato dispose o no


Private disposedValue As Boolean = False



' Implementazione del metodo Disposable.


Public Sub Dispose() Implements IDisposable.Dispose


' libero la memoria


Dispose(True)


GC.SuppressFinalize(Me)


End Sub




' IDisposable


Protected Overridable Sub Dispose(ByVal disposing As Boolean)


If Not Me.disposedValue Then


If disposing Then


'---codice per liberare le risorse non gestite chiamate in modo esplicito


End If


'libero le risorse non gestite condivise


End If


Me.disposedValue = True


End Sub



Protected Overrides Sub Finalize()


Dispose(False)


End Sub




Public Avviata As Boolean


'variabile pubblica che visualizza il valore imposto nel costruttore


Public Nome As String


'costruttore


Sub New()


Avviata = True


End Sub



'un costruttore che accetta un parametro


Sub New(ByVal NomePersona As String)


'imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona


End Sub


'costruttore che accetta più parametri


Sub New(ByVal NomePersona As String, ByVal CognomePersona As String)


Nome = NomePersona & " " & CognomePersona


End Sub




End Class


Esempio di utilizzo del metodo dispose nella form


Dim ObjRagazzo As New Ragazzo("Emanuele")


'visualizzo a video il valore della variabile nome


MessageBox.Show(ObjRagazzo.Nome)


'distruggo l'oggetto


ObjRagazzo.Dispose()





C#


class Ragazzo: IDisposable



{



//Implement IDisposable.


public void Dispose()


{


Dispose(true);


GC.SuppressFinalize(this);


}



protected virtual void Dispose(bool disposing)


{


if (disposing)


{


// libero la memoria dalla risorse non gestite chiamate in modo esplicito


}


// libero le risorse non gestite condivise



}



// distruttore per la classe


~Ragazzo()


{


// metodo dispose.


Dispose (false);


}



public bool Avviata;


//variabile pubblica che visualizza il valore imposto nel costruttore


public string Nome;


//Costruttore


public Ragazzo()


{


Avviata = true;


}



//il costruttore che accetta un parametro


public Ragazzo(string NomePersona)


{


//imposto la variabile pubblica con il valore del costruttore


Nome = NomePersona;




}


//costruttore che accetta più parametri


public Ragazzo(string NomePersona, string CognomePersona)


{


Nome = NomePersona + " " + CognomePersona;


}



}




Esempio di utilizzo del metodo dispose nella form


Ragazzo ObjRagazzo = new Ragazzo("Emanuele");


//visualizzo a video il valore della variabile nome


MessageBox.Show(ObjRagazzo.Nome);


ObjRagazzo.Dispose();



4.9 Gli eventi.


Con gli eventi, possiamo disporre alla classe o alla struttura di eseguire determinate azioni durante l’esecuzione del programma e notificare agli altri oggetti tale azione, tramite la parola chiave event possiamo creare degli eventi, e tramite la parola chiave RaiseEvent (VB.Net) inserito in un apposita routine, possiamo far si che l’evento si verifichi realmente. Inoltre negli eventi è possibile dichiarare argomenti, come per le routine, ma a differenza di essi non è possibile accettare argomenti di tipo paramarray o optional, né ottenere da essi valori di ritorno. Per default gli eventi sono di accesso di tipo pubblic (VB.Net) private (C#), in C# occorre creare un delegato public, Un delegato è un tipo che fa riferimento a un metodo. Una volta assegnato a un metodo, un delegato si comporta esattamente come il metodo cui è assegnato. Per avviare l'evento, definire un metodo da richiamare quando l'evento viene generato, in quel metodo, inserire il nome dell’evento, in questo modo verrà eseguito l’evento.


Di seguito si riporta un esempio di codice:


VB.Net


'classe che espone un evento (mangiare) e due metodi public


Class bambino


Event Mangiare(ByVal Cibo As String)



Sub Mangia()


'viene eseguito l'evento


RaiseEvent Mangiare("frutta")


'eventuale codice


End Sub



Sub beve()


'viene eseguito l'evento


RaiseEvent Mangiare("Beve")


'eventuale codice


End Sub


End Class



Esempio di utilizzo dell’evento mangiare.


Per eseguire l’evento, utilizziamo la nostra form, in alto, dopo la definizione di classe della form, scriviamo il seguente codice:


'intercetto l'evento


Dim WithEvents ObjBambino As New bambino




Tramite la parola chiave withevents dichiariamo una variabile con il compito di associare l’evento ad un nostro metodo, nell’ambiente di sviluppo Visual Studio 2005, nella casella combinata delle classi, viene visualizzato il nome della variabile, selezionando tale nome, nella casella combinata degli eventi viene visualizzato il nome dell’evento per quel oggetto, in questo modo selezionando tale voce, verrà scritta la procedura per l’evento.


Figura 4.5 – la casella combinata degli eventi per l’oggetto dichiarato tramite la parola chiave WithEvents.




Nell’evento, mangiare inseriamo del codice che visualizza il valore dell’evento mangiare


Private Sub oggetto_Mangiare(ByVal Cibo As String) Handles ObjBambino.Mangiare


MessageBox.Show(Cibo)


End Sub




Per eseguire tale evento, dobbiamo eseguire i metodi dell’oggetto creato con WithEvents, in questo modo viene eseguito l’evento mangiare. Di seguito si riporta il codice da inserire in un click di un pulsante o menu.


ObjBambino.Mangia()


ObjBambino.beve()




C#



//delegato dell'evento


public delegate void EventoMangiare(string cibo);



class Bambino


{


//implemento il delegato per l'evento


public event EventoMangiare Mangiare;


//viene eseguito l’evento


public void Mangia()


{


if (Mangiare != null)


{


Mangiare("Frutta");


//eventuale codice


}



}


//viene eseguito l’evento


public void Beve()


{


if (Mangiare != null)


{


Mangiare("Beve");


//eventuale altro codice


}


}



}






Esempio utilizzato in una form nell’evento click di un menu.


Bambino objBambino = new Bambino();



Dopo aver definito un oggetto della nostra classe, dobbiamo creare un gestore per l’evento della classe. Questo avviene, digitando il simbolo += dopo il nome dell’oggetto seguito da un punto ed il nome dell’evento, in questo modo si “aggancia” l’evento dell’oggetto ad una procedura, l’editor di Visual Studio 2005, ci consiglia di premere il tasto tab per completare la gestione dell’evento, come mostrato nella figura successiva



Figura 4.5- L’ambiente di sviluppo propone un suggerimento.



Subito dopo l’ambiente di sviluppo, ci consiglia di premere nuovamente il tasto TAB per creare un metodo che ha il compito di fare da gestore per l’evento della classe. Di seguito si riporta tale figura



Figura 4.6- L’ambiente di sviluppo propone un suggerimento per creare un gestore degli eventi.



Terminata la fase di creazione della gestore degli eventi, eseguiamo i metodi del nostro oggetto, in questo modo viene scatenato l’evento della nostra classe di seguito si riporta il codice completo.


//creo l'oggetto


Bambino objBambino = new Bambino();


//creo un gestore degli eventi


objBambino.Mangiare += new EventoMangiare(objBambino_Mangiare);


//eseguo i metodi della classe


objBambino.Mangia();


objBambino.Beve();



Nel gestore degli eventi creato automaticamente in precedenza, scriviamo del codice che visualizza a video un messaggio.


//gestore dell'evento per la classe bambino


void objBambino_Mangiare(string cibo)


{


//viualizzo a video un messaggio con il valore dell'evento


MessageBox.Show(cibo);


}



Tramite il simbolo += associamo l’evento ad una nostra funzione, un evento è simile a un campo, tuttavia l'accesso a tale campo è sottoposto a notevoli restrizioni. Le uniche operazioni consentite sono la composizione di un nuovo delegato su tale campo e la rimozione di un delegato dal campo, eventualmente composto.



Questa operazione viene eseguita tramite gli operatori += e -=. Per dare inizio alla ricezione di chiamate di un evento, il codice client crea per prima cosa un delegato del tipo di evento che fa riferimento al metodo che l'evento deve richiamare. Compone quindi tale delegato con eventuali altri delegati cui l'evento è connesso mediante +=.



Pertanto, quando si richiama un evento, viene dapprima verificato che il campo del tipo di delegato non sia nullo, per poi chiamare l'evento. Ecco perché nella classe si è verificato se il campo è nullo o no per evitare eccezioni.


Per rimuovere l’associazione di un evento si utilizza il simbolo -=


objBambino.Mangiare -= new EventoMangiare(objBambino_Mangiare);


Durante l’esecuzione del programma, possiamo associare un evento a un gestore eventi, questo avviene tramite la parola chiave AddHandler (VB.Net), il comando AddHandler che accetta due argomenti, l’evento che si vuole reindirizzare ad una procedura e l’indirizzo della procedura che gestisce l’evento. Permette di creare delle procedure (che hanno la stessa firma dell’evento) che verranno richiamate ogni qualvolta che si scatena l’evento dell’oggetto associato.


VB.Net


'altro gestore degli eventi


Dim objBambino2 As New bambino


'associo l'evento della classe alla procedura


AddHandler objBambino2.Mangiare, AddressOf Me.Mangio


'non appena eseguo il metodo, viene eseguito la procedura (mangio)associata all’evento


objBambino2.Mangia()



'procedura che fa da gestore dell'evento, come si vede manca la parola chiave handles


Private Sub Mangio(ByVal cibo As String)


MessageBox.Show(cibo)


End Sub



Mentre per rimuovere il gestore degli eventi, si utilizza la parola chiave RemoveHandler.



'rimuovo il gestore degli eventi


RemoveHandler objBambino2.Mangiare, AddressOf Me.Mangio









5.0 Ereditarietà.


Questo termine della programmazione ad oggetti, è molto importante. Infatti consiste nella possibilità di derivare una nuova classe da una classe esistente detta anche classe base. La classe derivata eredita tutti i campi, le proprietà i metodi e gli eventi dalla classe base e può modificare il comportamento di proprietà e metodi, può estenderli o aggiungerli degli altri. Con l’ereditarietà possiamo riutilizzare le classi esistente come classi basi ed implementare la nuova classe, scrivendo soltanto il codice per la nuova funzionalità. Un esempio di ereditarietà può essere il mondo animale, dove animale è la classe base, da essa si ereditano altre classi come per esempio la classe mammifero, la classe felino, la classe carnivoro ecc.


Per ereditare da una classe esistente si utilizza la parola chiave inherits (VB.Net) seguito dal nome della classe da ereditare oppure il simbolo : (C#) seguito dal nome della classe da ereditare.


Supponiamo di creare una classe, che eredita dalla classe persona creata in precedenza, di seguito riportiamo un esempio.


VB.Net


Classe persona


Class Persona


'variabile della proprietà nazionalità


Private m_Nazionalita As String


'questa variabie non è accessibile al di fuori della classe


Private Nome As String


'questa è visibile anche fuori dalla classe


Public Cognome As String


'evento


Public Event Nutrirsi(ByVal cibo As String)


'metodo condiviso


Public Shared Sub Messaggio()


MessageBox.Show("Inserire tutti i dai")


End Sub


'metodo che solleva l'evento


Public Sub Mangia()


'viene eseguito l'evento


RaiseEvent Nutrirsi("Carne")


'eventuale codice


End Sub



'metodo che solleva l'evento


Public Sub Beve()


'viene eseguito l'evento


RaiseEvent Nutrirsi("Acqua")


'eventuale codice


End Sub


'metodo che visualizza un messaggio, cambiato con la parola overloads


Public Overloads Sub Visualizza()


'visualizza a video il valore del campo cognome


MessageBox.Show(Cognome)


End Sub


'overload del metodo visualizza


Public Overloads Sub Visualizza(ByVal nome As String)


'visualizzo un messaggio a video con il valore che viene passato


MessageBox.Show(nome & " " & Cognome)


End Sub


'overload del metodo visualizza con un diverso tipo


Public Overloads Sub Visualizza(ByVal sesso As Boolean)


'visualizzo un messaggio a video


If sesso = True Then


MessageBox.Show("Uomo" & " " & Cognome)


Else


MessageBox.Show("Donna" & " " & Cognome)


End If



End Sub


'overload del metodo visualizza con più paramatri


Public Overloads Sub Visualizza(ByVal nome As String, ByVal sesso As Boolean)


'visualizzo un messaggio a video


If sesso = True Then


MessageBox.Show("Uomo" & " " & nome & Cognome)


Else


MessageBox.Show("Donna" & " " & nome & Cognome)


End If



End Sub


'proprietà che identifica la nazionalità


Property nazionalita() As String


Get


'restituisce il valore


Return m_Nazionalita


End Get


Set(ByVal value As String)


'imposta il valore


m_Nazionalita = value


End Set


End Property



'variabile per la proprietà occhiali


Dim mOcchiali As String = "No"


ReadOnly Property Occhiali() As String


Get


Return mOcchiali


End Get



End Property


'variabile per la proprietà fumatore


Dim mFumatore As Boolean


WriteOnly Property Fumatore() As Boolean


Set(ByVal value As Boolean)


mFumatore = value


End Set


End Property


'variabile per la proprietà sesso


Dim m_sesso As String


''Proprietà che controlla il valore se è uomo o donna


Public Property sesso() As String


Get


Return m_sesso


End Get


Set(ByVal value As String)



If value.ToLower = "uomo" Or value.ToLower = "donna" Then


m_sesso = value


Else


Throw New Exception("Inserire uno dei seguenti valori uomo o donna")


End If




End Set


End Property



''' <summary>


''' metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


''' </summary>


''' <param name="DataNascita"> data di nascita </param>


''' <returns>un valore relativo agli anni</returns>


Public Function Anni(ByVal DataNascita As DateTime) As Integer



Return DateTime.Now.Year - DataNascita.Year



End Function



End Class





Classe nuova, che eredita dalla classe persona


Class Giovane


Inherits Persona



End Class



Va ricordato che si può scrivere anche in forma contratta, ossia nel seguente modo.


'classe che eredita dalla classe persona


Class Giovane : Inherits Persona




End Class



Esempio di codice in una form, da notare che vengono ereditati anche i membri dichiarati come shared e gli eventi come riportato qui di seguito.



Dim ObjGiovane As New Giovane()


'campo della classe base ossia persona - ereditato


ObjGiovane.Cognome = "Mattei"


'Proprietà della classe base - ereditato


ObjGiovane.nazionalita = "Italiana"


'metodo della classe base - ereditato.


ObjGiovane.Visualizza("Emanuele")


'viene erediato anche il metodo definito come shared


Giovane.Messaggio()


'evento della classe base -ereditato


AddHandler ObjGiovane.Nutrirsi, AddressOf Me.Evento_Nutrirsi


'scateno l'evento - metodo ereditato


ObjGiovane.Mangia()


'scateno un altro evento - metodo ereditato


ObjGiovane.Beve()



'gestore dell'evento della classe ereditata


Private Sub Evento_Nutrirsi(ByVal cibo As String)


MessageBox.Show(cibo)


End Sub


C#


Classe persona


//delegato dell'evento


public delegate void EventoNutrirsi(string cibo);


class Persona


{


//variabile della proprietà nazionalità


private string mNazionalita;


//questa variabie non è accessibile al di fuori della classe


private string Nome;


//questa è visibile anche fuori dalla classe


public string Cognome;


//implemento il delegato per l'evento


public event EventoNutrirsi Nutrirsi;


public void Mangia()


{


//viene eseguito l’evento


if (Nutrirsi != null)


{


//scateno l'evento


Nutrirsi("Carne");


//eventuale codice


}



}


//viene eseguito l’evento


public void Beve()


{


if (Nutrirsi != null)


{


//scateno l'evento


Nutrirsi("Acqua");


//eventuale altro codice


}


}


//metodo statico visualizza un messaggio


public static void Messaggio()


{


MessageBox.Show("Inserire i dati");



}


//metodo che visualizza un messaggio


public void Visualizza()


{


//visualizza a video il valore del campo cognome


MessageBox.Show( Cognome);


}


//overload del metodo visualizza


public void Visualizza(string nome)


{


MessageBox.Show(nome + " " + Cognome);


}


//overload del metodo visualizza con un diverso tipo


public void Visualizza(bool sesso)


{


if (sesso == true)


{


MessageBox.Show("Uomo" + " " + Cognome);



}


else


{


MessageBox.Show("Donna" + " " + Cognome);



}


}



//overload del metodo visualizza con più paramatri


public void Visualizza(string nome, bool sesso)


{


if (sesso == true)


{


MessageBox.Show("Uomo" + " " + nome + Cognome);



}


else


{


MessageBox.Show("Donna" + " " + nome + Cognome);



}



}


//proprietà che identifica la nazionalità.


public string Nazionalita


{


get


{


//restituisco il valore della proprietà


return mNazionalita;



}


set


{


//imposto il valore della proprietà


mNazionalita = value;


}



}


//variabile per la proprietà occhiali


string mOcchiali = "No";


//proprietà occhiali di sola lettura


public string Occhiali


{


get


{


return mOcchiali;


}



}


//variabile per la proprietà fumatore


bool mFumatore;


//proprietà di sola scrittura


public bool Fumatore


{



set


{


mFumatore = value;


}



}



//variabile per la proprietà sesso


string mSesso;


//Proprietà che controlla il valore se è uomo o donna


public string sesso


{


get


{



return mSesso;


}


set



{


//verifico che il dato inserito sia corretto


if ((value.ToLower() =="uomo") (value.ToLower() =="donna"))


{


mSesso = value ;


}


else


{


//sollevo un eccezione con un messaggio


throw new Exception("Inserire uno dei seguenti valori uomo o donna");


}




}




}





//metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


/// <summary>


/// metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


/// </summary>


/// <param name="DataNascita"> data di nascita</param>


/// <returns>un valore relativo agli anni </returns>


public int Anni(DateTime DataNascita)


{




return DateTime.Now.Year - DataNascita.Year;



}




}



Classe nuova che eredita dalla classe persona


//classe che eredita dalla classe persona


class Giovane : Persona


{




}



Esempio di codice in una form, da notare che vengono ereditati anche i membri dichiarati come static e gli eventi come riportato qui di seguito.


Giovane ObjGiovane = new Giovane();


//campo della classe base ossia persona - ereditato


ObjGiovane.Cognome = "Mattei";


//Proprietà della classe base - ereditato


ObjGiovane.Nazionalita = "Italiana";


//metodo della classe base - ereditato.


ObjGiovane.Visualizza("Emanuele");


//viene erediato anche il metodo definito come static


Giovane.Messaggio();


//evento della classe base -ereditato


ObjGiovane.Nutrirsi += new EventoNutrirsi(ObjGiovane_Nutrirsi);


//scateno l'evento - metodo ereditato


ObjGiovane.Mangia();


//scateno un altro evento - metodo ereditato


ObjGiovane.Beve();




//gestore dell'evento nutrirsi


void ObjGiovane_Nutrirsi(string cibo)


{


MessageBox.Show(cibo);


}




Abbiamo visto come da una nuova classe possiamo ereditare una classe esistente.La nuova classe, inoltre, è possibile estenderla con nuovi campi metodi, proprietà ed eventi.


Di seguito si riporta un esempio di codice.


VB.Net


Classe ereditata


'classe che eredita dalla classe persona


Class Giovane


Inherits Persona


'estendo la nuova classe con un nuovo campo ed una nuova proprietà


Public Studente As Boolean


'nuova proprietà


Private m_attivitaSportiva As String


Public Property AttivitaSportiva() As String


Get


Return m_attivitaSportiva


End Get


Set(ByVal value As String)


m_attivitaSportiva = value


End Set


End Property


End Class


Utilizzo in una form, imposto la proprietà ed il campo aggiunti alla classe ereditata


Dim ObjGiovane As New Giovane()


'imposto la proprietà aggiunta alla classe ereditata


ObjGiovane.AttivitaSportiva = "Calcio"


'imposto la variabile aggiunta alla classe ereditata


ObjGiovane.Studente = True


'visualizzo un messaggio a video


MessageBox.Show("Studente: " & ObjGiovane.Studente & " " & "Sport: " & ObjGiovane.AttivitaSportiva)



C#


Classe ereditata


class Giovane : Persona


{


//estendo la nuova classe con un nuovo campo ed una nuova proprietà


public bool Studente;


//nuova proprietà


private string mAttivitaSportiva;


public string AttivitaSportiva


{


get


{


return mAttivitaSportiva;


}


set


{


mAttivitaSportiva = value;


}


}



}



Utilizzo in una form, imposto la proprietà ed il campo aggiunti alla classe ereditata.


Giovane ObjGiovane = new Giovane();


//imposto la proprietà aggiunta alla classe ereditata


ObjGiovane.AttivitaSportiva = "Calcio";


//imposto la variabile aggiunta alla classe ereditata


ObjGiovane.Studente = true;


//visualizzo un messaggio a video


MessageBox.Show("Studente: " + ObjGiovane.Studente + " " + "Sport: " + ObjGiovane.AttivitaSportiva);





La chiamata di un costruttore da una classe ereditata.


Quando si eredita una classe, se la classe base ha un costruttore che accetta argomenti è obbligatorio creare un costruttore. Diverso è il discorso se la classe base non ha un costruttore o è privo di argomenti. Tramite la parola chiave mybase (VB.Net) o base (C#) possiamo richiamare i vari costruttori della classe base.


VB.Net


Definizioni della classe base


'classe base con un costruttore che accetta un argomento


Class Uomo


Private Nome As String


Sub New(ByVal nomepersona As String)


Nome = nomepersona


End Sub


'variabile pubblica


Public anni As Byte


'metodo pubblico


Public Sub Visualizza()


MessageBox.Show(Nome)


End Sub



End Class



Definizione della classe secondaria


'classe che eredita dalla classe uomo


Class umano


Inherits Uomo


'costruttore


Sub New(ByVal Nome As String)


'richiamo il costruttore della classe base


MyBase.New(Nome)


End Sub


End Class



Esempio di codice da utilizzare in una form


'creo un nuovo oggetto della classe secondaria passando un valore al costruttore


Dim objUmano As New umano("Emanuele")


'imposto la variabile ereditata


objUmano.anni = 32


'eseguo il metodo ereditato


objUmano.Visualizza()


C#


Definizione della classe base


//classe base con un costruttore che accetta un argomento


class Uomo


{


private string nome;


//costruttore


public Uomo(string nomepersona)


{


nome = nomepersona;


}


//variabile pubblica


public byte anni;


//metodo pubblico


public void Visualizza()


{


MessageBox.Show(nome);


}


}


Definizione della classe secondaria


//classe che eredita dalla classe uomo


class Umano : Uomo


{


public Umano(string nome) : base(nome)


{



}


}


Esempio di codice da utilizzare in una form.


//creo un nuovo oggetto della classe secondaria passando un valore al costruttore


Umano ObjUmano = new Umano("Emanuele");


//imposto la variabile ereditata


ObjUmano.anni = 32;


//eseguo il metodo ereditato


ObjUmano.Visualizza();



Nella nuova classe possiamo avere più costruttori o costruttori con argomenti in più.


Si riporta un esempio di codice.



VB.Net


Classe secondaria con un nuovo costruttore


Class umano


Inherits Uomo


'variabile pubblica


Public Cognome As String


'costruttore


Sub New(ByVal Nome As String)


'richiamo il costruttore della classe base


MyBase.New(Nome)


End Sub


'altro costruttore con più argomenti


Sub New(ByVal nome As String, ByVal CognomePersona As String)


MyBase.New(nome)


Cognome = CognomePersona


End Sub


End Class



Esempio di codice, utilizzato in una form


'utilizzo il secondo costruttore


Dim objumano2 As New umano("Emanuele", "Mattei")


'visualizzo a video il valore della variabile pubblica


MessageBox.Show(objumano2.Cognome)





C#


Classe secondaria con un nuovo costruttore


class Umano : Uomo


{


//variabile pubblica


public string Cognome;


public Umano(string nome) : base(nome)


{



}


//altro costruttore con più argomenti


public Umano(string nome, string cognome)


: base(nome)


{


Cognome = cognome;


}



}


Esempio di codice utilizzato in una form


//utilizzo il secondo costruttore


Umano objUmano2 = new Umano("Emanuele", "Mattei");


//visualizzo a video il valore della variabile pubblica


MessageBox.Show(objUmano2.Cognome);




Ridefinire i membri della classe – Polimorfismo


In una nuova classe, possiamo ridefinire il comportamento di un membro di una classe base, rispettando così la regola del polimorfismo, In pratica, uno stesso nome indica un comportamento diverso, da non confondere con il sovraccaricamento il quale, invece, consiste nel dichiarare più versioni di una funzione ma di ogni versione è associata una firma diversa(tipo o parametri). Mentre con il ridefinire viene modificato il comportamento e no la firma.


Per modificare il comportamento di un metodo o proprietà di una classe secondaria, occorre utilizzare la parola chiave overridable (VB.Net) virtual (C#) per la classe base, e la parola chiave overrides (VB.Net) override (C#) per la classe secondaria. Va ricordato che la parola chiave overridable (VB.Net) non può essere utilizzata con la parola chiave MustOverride, NotOverridable o Shared. Mentre la parola chiave virtual (C#) non può essere utilizzata con la parola chiave static, abstract e override per impostazione predefinita i metodi non sono virtuali e non possono essere sottoposti a override.


VB.Net


Definizione della classe base


Class Uomo


Private Nome As String


Sub New(ByVal nomepersona As String)


Nome = nomepersona


End Sub


'variabile pubblica


Public anni As Byte


'metodo pubblico


Public Sub Visualizza()


MessageBox.Show(Nome)


End Sub


'metodo che può essere ridefinito


Overridable Sub Nominativo()


Console.Write(Nome)


End Sub


End Class


Definizione della classe secondaria


Class umano


Inherits Uomo


'variabile pubblica


Public Cognome As String


'costruttore


Sub New(ByVal Nome As String)


'richiamo il costruttore della classe base


MyBase.New(Nome)


End Sub


'altro costruttore con più argomenti


Sub New(ByVal nome As String, ByVal CognomePersona As String)


MyBase.New(nome)


Cognome = CognomePersona


End Sub



'metodo a cui modifico il comportamento


Public Overrides Sub Nominativo()


MessageBox.Show(Cognome)


End Sub


End Class


Esempio di codice utilizzato nella form


'oggetto della classe secondaria


Dim ObjUmano As New umano("Emanuele", "Mattei")


'eseguo il metodo ridefinito


ObjUmano.Nominativo()



C#


Definizione della classe base


class Uomo


{


private string nome;


//costruttore


public Uomo(string nomepersona)


{


nome = nomepersona;


}


//variabile pubblica


public byte anni;


//metodo pubblico


public void Visualizza()


{


MessageBox.Show(nome);


}


//metodo che può essere ridefinito


public virtual void Nominativo()


{


Console.Write(nome);


}



}


Definizione della classe secondaria


class Umano : Uomo


{


//variabile pubblica


public string Cognome;


public Umano(string nome) : base(nome)


{



}



//altro costruttore con più argomenti


public Umano(string nome, string cognome)


: base(nome)


{


Cognome = cognome;


}


//metodo a cui modifico il comportamento


public override void Nominativo()


{


MessageBox.Show(Cognome);


}



}


Esempio di codice utilizzato nella form


//oggetto della classe secondaria


Umano ObjUmano = new Umano("Emanuele", "Mattei");


//eseguo il metodo ridefinito


ObjUmano.Nominativo();




Tramite la parola chiave Mybase (VB.Net) o base (C#) seguito da un punto e nomemembro, come viene anche suggerito dall’ambiente di sviluppo Visual Studio 2005, nel momento in cui scriviamo un campo, proprietà o metodo ridefinibile, ci permette di richiamare tale membro della classe base nella classe derivata. Riprendendo l’esempio precedente, la classe secondaria sarà modificata in questo modo:


VB.Net


Classe secondaria


Class umano


Inherits Uomo


'variabile pubblica


Public Cognome As String


'costruttore


Sub New(ByVal Nome As String)


'richiamo il costruttore della classe base


MyBase.New(Nome)


End Sub


'altro costruttore con più argomenti


Sub New(ByVal nome As String, ByVal CognomePersona As String)


MyBase.New(nome)


Cognome = CognomePersona


End Sub



'metodo a cui modifico il comportamento


Public Overrides Sub Nominativo()


'invoco il metodo della classe base


MyBase.Nominativo()


MessageBox.Show(Cognome)


End Sub


End Class



C#


Classe secondaria


class Umano : Uomo


{


//variabile pubblica


public string Cognome;


public Umano(string nome) : base(nome)


{



}



//altro costruttore con più argomenti


public Umano(string nome, string cognome)


: base(nome)


{


Cognome = cognome;


}


//metodo a cui modifico il comportamento


public override void Nominativo()


{


//invoco il metodo della classe base


base.Nominativo();


MessageBox.Show(Cognome);


}




}


In una classe derivata, possiamo far si che una proprietà o metodo non può essere ridefinito, tramite la parola chiave NotOverridable (VB.Net) o sealed (C#). Supponiamo di avere una classe (A) che ha un metodo che può essere ereditato, la classe b, a sua volta eredita tale metodo ma lo rende in modo che non può essere ridefinibile ossia override da notare che la parola chiave sealed di C#, vieta che un membro o la classe venga ereditata.


VB.Net


'classe base


Class A


Public Nome As String


Public Overridable Sub Visualizza()


MessageBox.Show("classe A")


End Sub


End Class


'classe secondaria che eredita dalla classe A


Class B


Inherits A


'metodo che non può essere ridefinito


Public NotOverridable Overrides Sub Visualizza()


MessageBox.Show("Classe B")


End Sub


End Class



Class C


Inherits B


'non posso effettuare overrides del metodo visualizza



End Class



C#


//classe base


class A


{


public string Cognome;


public virtual void Visualizza()


{


MessageBox.Show("Classe A");


}


}


//classe secondaria che eredita dalla classe A


class B : A


{


//metodo che non può essere ridefinito


public sealed override void Visualizza()


{


MessageBox.Show("Classe B");


}




}


class C : B


{


//non posso effettuare overrides del metodo visualizza



}


Nascondere un membro della classe base – Shadows


In Visual Basic Net, si ha una parola chiave denominata Shadows, essa permette di nascondere un elemento membro, della classe base in una classe derivata. Vuol dire se abbiamo una classe secondaria, che eredita alcuni campi o metodi o proprietà da un’altra classe e questa presenta alcuni membri con lo stesso nome, possiamo far si che vengono presi in considerazioni i membri della classe secondaria.


Lo scopo principale dello shadowing è di proteggere la definizione dei membri della classe. È possibile che la classe base sia sottoposta a una modifica che crea un elemento con lo stesso nome di quello già definito. In tal caso, il modificatore Shadows impone che i riferimenti attraverso la classe vengano risolti nel membro definito, anziché nel nuovo elemento della classe base. Non è possibile utilizzarla insieme ai marcatori Overloads, Overrides o Static.






VB.Net


Classe base


Class ClasseA


Public Nome As String = "Classe A"



End Class


Classe secondaria


Class ClasseB


Inherits ClasseA


'stesso nome della variabile della classe base


Public Shadows Nome As String = "Classe B"


End Class


Esempio di utilizzo del codice in una form


'creo un oggetto delle classe B che eredita dalla classe A


Dim ObjClasseB As New ClasseB


'visualizzo il valore della variabile Nome


MessageBox.Show(ObjClasseB.Nome)




Se invece si vuole accedere all’elemento della classe base, occorre utilizzare la parola chiave mybase


Classe secondaria


Class ClasseB


Inherits ClasseA


'stesso nome della variabile della classe base


Public Shadows Nome As String = "Classe B"


'visualizzo il valore della variabile della classe base


Public Sub VisualizzaNome()


MessageBox.Show(MyBase.Nome)


End Sub



End Class


Esempio di codice in una form


'creo un oggetto delle classe B che eredita dalla classe A


Dim ObjClasseB As New ClasseB


'visualizzo il valore della variabile della classe base


ObjClasseB.VisualizzaNome() 'Risultato Classe A


Annullamento del shadowing


Se nel caso un elemento è dichiarato come private lo shadowing viene annullato, di seguito si riporta un esempio di codice in cui nella classe base il metodo “Messaggio” viene dichiarato come public mentre nella nuova classe, viene dichiarato come private, in questo caso il metodo utilizzato sarà quello della classe base.


Classe Base


Class ClasseA


Public Nome As String = "Classe A"


'metodo public


Public Sub Messaggio()


MessageBox.Show("Classe A")


End Sub


End Class


Classe secondaria


Class ClasseB


Inherits ClasseA


'stesso nome della variabile della classe base


Public Shadows Nome As String = "Classe B"


'metodo con lo stesso nome della classe base ma il shadowing annullato perché è private


Private Shadows Sub Messaggio()


MessageBox.Show("Classe B")


End Sub


'visualizzo il valore della variabile della classe base


Public Sub VisualizzaNome()


MessageBox.Show(MyBase.Nome)


End Sub


End Class


Esempio di codice in una form.


'creo un oggetto delle classe B che eredita dalla classe A


Dim ObjClasseB As New ClasseB


'Eseguo il metodo ma viene eseguito quello della classe base il risultato sarà “Classe A”


ObjClasseB.Messaggio()




In C# possiamo utilizzare il modificatore new, in questo modo possiamo nascondere un membro ereditato da un membro della classe base.


Prendendo spunto dall’esempio precedente, si riporta il codice in versione C#, tramite l’utilizzo del modificatore new.


C#


Classe base


class ClasseA


{


public string Nome = "Classe A ";


//metodo public


public void Messaggio()


{


MessageBox.Show("Classe A ");


}


}



Classe secondaria


class ClasseB : ClasseA


{


//stesso nome della variabile della classe base


public new string Nome = "Classe B";


//metodo che visualizza il valore della variabile della classe base


public void VisualizzaNome()


{


MessageBox.Show(base.Nome);



}


//metodo con lo stesso nome della classe base ma il new viene annulatto perché è private


private new void Messaggio()


{


MessageBox.Show("Classe B");


}



}



Esempio di codice in una form


ClasseB ObjClasseB = new ClasseB();


//visualizzo il valore della variabile Nome della classe secondaria il valore è: Classe B


MessageBox.Show(ObjClasseB.Nome);


//visualizzo il valore della variabile della classe base Visualizza il valore: Classe A


ObjClasseB.VisualizzaNome();


//Eseguo il metodo ma viene eseguito quello della classe base il risultato sarà “Classe A”


ObjClasseB.Messaggio();




Creazione delle classi astratte


Con le classi Astratte possiamo impedire di utilizzare una classe così com’è , obbligandoli invece a derivare da tale classe, in questo modo, la classe viene denominata astratta, in quanto è possibile utilizzarla solo per derivare nuove classi e non può essere direttamente istanziata. Tramite le parole chiavi MustInherit (VB.Net o Abstract (C#) possiamo creare delle classi astratte.


Il modificatore abstract può essere utilizzato insieme a classi, metodi, proprietà indicizzatori ed eventi. Utilizzare il modificatore abstract in una dichiarazione di classe per indicare che una classe può essere utilizzata soltanto come classe base di altre classi. I membri contrassegnati come astratti o inclusi in una classe astratta devono essere implementati da classi che derivano dalla classe astratta.


Va ricordato che in C# non è possibile creare istanze di classi estratte, non si può modificare una classe astratta con il modificatore saeled ma può contenere metodi e funzioni di accesso astratti. Mentre in VB.Net si può personalizzare una determinata funzione o proprietà dalla classe astratta, in questo caso occorre utilizzare la parola chiave MustOverride, in questo modo sarà possibile modificare il comportamento di un metodo o proprietà.



VB.Net


Classe base (astratta)


MustInherit Class ClasseC


'modifico il metodo


Public MustOverride Sub Messaggio()


'modifico la proprietà


Public MustOverride Property NomeClasse() As String


End Class



Classe secondaria


Class ClasseDerivata


Inherits ClasseC


Private mNome As String


'implemento la proprietà


Public Overrides Property NomeClasse() As String


Get


Return mNome


End Get


Set(ByVal value As String)


mNome = value


End Set


End Property


'personalizzo il metodo


Public Overrides Sub Messaggio()


mNome = "Classe Derivata"


End Sub


End Class



Esempio di codice da utilizare in una form.


'creo dalla classe secondaria un istanza


Dim ObjClasseDerivata As New ClasseDerivata()


'eseguo il metodo


ObjClasseDerivata.Messaggio()


'visualizzo il valore della proprietà


MessageBox.Show(ObjClasseDerivata.NomeClasse)



C#


Classe base (astratta)


abstract class ClasseC


{


public abstract string NomeClasse { get; }


public abstract void Messaggio();



}



Classe secondaria


class ClassDerivata : ClasseC


{


private string Nome;


//effettuo l'override della proprietà


public override string NomeClasse


{


get { return Nome ; }


}


//ridefinisco il metodo


public override void Messaggio()


{


Nome = "Classe Derivata";


}



}



Esempio di codice da utilizzare nella form.


//creo dalla classe secondaria un istanza


ClassDerivata ObjClassDerivata = new ClassDerivata();


//eseguo il metodo


ObjClassDerivata.Messaggio();


//visualizzo il valore della proprietà


MessageBox.Show(ObjClassDerivata.NomeClasse);


//ClasseC OBjClasseC = new ClasseC(); //errore non si può fare un instanza da una classe astratta.










Evitare l’ereditarietà delle classi


Se nel caso si vuole evitare che una classe venga ereditata, si può utilizzare la parola chiave NotInheritable (VB.Net) o sealed (C#)


Esempio di codice


VB.Net


Classe base


NotInheritable Class ClassePrima


Public nome As String


End Class



Classe secondaria


'errore non è possibile ereditare


Class ClasseSEconda


Inherits ClassePrima


End Class



C#


Classe base


sealed class ClassePrima


{


public string Nome;


}



Classe secondaria


//errore non è possibile ereditare


class ClasseSeconda : ClassePrima


{


public string nome;



}



Il qualificatore Protected


Tramite il qualificatore protected, possiamo impostare una certa visibilità ad una classe ed ai suoi membri, in modo che essi possono essere visibili anche ad una classe derivata, si comporta come il qualificatore private solo con la con la differenza che è visibile anche alle classi derivate.


Di seguito si riporta un esempio di codice, la classe base chiamata donna, ha una variabile di tipo string, con accessibilità di tipo protected. Tale variabile è visibile alla classe ereditata, denominata bambina, ma non all’esterno di essa. Inoltre il metodo VisualizzaNome, permette di visualizza a video tramite una messagebox il valore di quel campo.


VB.Net


Classe base


'classe che ha una variabile con il qualificatore protected


Class Donna


Protected nome As String = "Classe Donna"



End Class



Classe derivata


'classe derivata


Class Bambina


Inherits Donna


'metodo che visualizza il valore del campo nome impostato come protected.


Public Sub VisualizzaNome()


MessageBox.Show(nome)


End Sub


End Class



Esempio di codice da utilizzare in una form


'creo un istanza della classe bambina


Dim ObjBambina As New Bambina()


'errore non è accessibile


'ObjBambina.nome = "Valore"


'eseguo il metodo che mi visualizza il valore del campo protected


ObjBambina.VisualizzaNome()



C#


Classe base


//classe che ha una variabile con il qualificatore protected


class Donna


{


protected string Nome = "Classe Donna";


}



Classe derivata


//classe derivata


class Bambina : Donna


{


//metodo che visualizza il valore del campo nome impostato come protected.


public void VisualizzaNome()


{


MessageBox.Show(Nome);


}


}



Esempio di codice da utilizzare in una form


//creo un istanza della classe bambina


Bambina ObjBambina = new Bambina();


//errore non è accessibile


//ObjBambina.nome = "Valore";


//eseguo il metodo che mi visualizza il valore del campo protected


ObjBambina.VisualizzaNome();




Il qualificatore Friend – Internal


Con il qualificatore Friend (VB.Net) e Internal (C#) applicato a classi o membri, permette di renderli visibili sono all’interno dello assembley ma non dall'esterno dell'assembly.



4.9 Le Interfacce.


Le interfacce non possono contenere né codice né dati membri, ma sono, semplicemente, un gruppo di nomi di metodi e di firme; esse definiscono ciò che una classe può possedere, ma non implementano alcuna funzionalità; includono soltanto funzioni, proprietà, eventi o indicizzatori e non possono avere dati membro, costruttori o distruttori. Tutti questi membri sono ad accesso di tipo public.


Di seguito si riporta un interfaccia che espone proprietà e funzioni, da notare in VB.Net, che le proprietà e le funzioni non terminano con end property e end sub.


VB.Net


Sintassi


Interfacce nomeInterfaccia


---codice


End interface



Interfaccia


'interfaccia con proprietà e funzioni


Public Interface capelli


'dichiaro una proprietà di tipo string


Property Colore() As String


'metodo


Sub Lavaggio()


'proprietà di sola lettura


ReadOnly Property Lunghezza() As String


'proprietà di sola scrittura


WriteOnly Property Tagliati() As Boolean


End Interface



C#


Sintassi


interface NomeInterfaccia


{


}



Interfaccia


//interfaccia con proprietà e funzioni


public interface ICapelli


{


//dichiaro una proprietà di tipo string


string Colore


{


get;


set;


}


//metodo


void Lavaggio();


//proprietà di sola lettura


string Lunghezza


{


get;


}


//proprietà di sola scrittura


bool Tagliati


{


set;


}


}



Per utilizzarla in una classe, occorre utilizzare la parola chiave implements, si noti in VB.net che dopo aver digitato la parola implements, l’ambiente di sviluppo ci suggerisce (figura 5) le interfacce che si hanno a disposizione, dopo aver selezionato quella corretta (capelli) digitando il pulsante invio, verranno aggiunti automaticamente le varie implementazioni, mentre in C# dopo aver digitato il nome dell’interfaccia, tenere premuto la sequenza dei tasti maiuscolo+alt+f10, il quale visualizza le voci per l’implementazione dell’interfaccia.



Figura 4.7 – L’ambiente di sviluppo (VB.NET) ci suggerisce le interfaccia disponibili.





Figura 4.8– L’ambiente di sviluppo (C#) ci suggerisce le implementazioni per l’interfaccia


Di seguito si riporta un esempio dell’utilizzo dell’interfaccia dichiarata precedentemente in una classe


VB.Net


'Classe che utilizza l'interfaccia


Class ragazza


Implements ICapelli



Public Property Colore() As String Implements ICapelli.Colore


Get


'codice da aggiungere


End Get


Set(ByVal value As String)


'codice da aggiungere


End Set


End Property



Public Sub Lavaggio() Implements ICapelli.Lavaggio


'codice da aggiungere


End Sub



Public ReadOnly Property Lunghezza() As String Implements ICapelli.Lunghezza


Get


'codice da aggiungere


End Get


End Property



Public WriteOnly Property Tagliati() As Boolean Implements ICapelli.Tagliati


Set(ByVal value As Boolean)


'codice da aggiungere


End Set


End Property


End Class


C#


class Ragazza : ICapelli


{




#region ICapelli Membri di



public string Colore


{


get


{


//codice da aggiungere


}


set


{


//codice da aggiungere


}


}



public void Lavaggio()


{


//codice da aggiungere


}



public string Lunghezza


{


get


{


//codice da aggiungere


}


}



public bool Tagliati


{


set


{


//codice da aggiungere


}


}



#endregion


}




L’esempio riportato qui di seguito è in ambiente application, il quale una impostato i valori della classe Ragazza, visualizza a video le informazioni.



VB.Net


La classe con il codice completo.


'Classe che utilizza l'interfaccia


Class ragazza


Implements ICapelli


'variabile per la proprietà colore


Private mColore As String


'variabile per la proprietà lunghezza


Dim mLunghezza As String = "Corti"


'variabile per la proprietà tagliati


Dim mTagliati As Boolean = False


Public Property Colore() As String Implements ICapelli.Colore


Get


Return mColore


End Get


Set(ByVal value As String)


mColore = value


End Set


End Property


'metodo che visualizza un messaggio a video


Public Sub Lavaggio() Implements ICapelli.Lavaggio


MessageBox.Show("Solo con lo shampoo")


End Sub


'


Public ReadOnly Property Lunghezza() As String Implements ICapelli.Lunghezza


Get


If mTagliati = True Then


mLunghezza = "Corti"


Else


mLunghezza = "Lunghi"


End If


Return mLunghezza


End Get


End Property



Public WriteOnly Property Tagliati() As Boolean Implements ICapelli.Tagliati


Set(ByVal value As Boolean)


mTagliati = value


End Set


End Property


End Class



Esempio di utilizzo in una form, nell’evento click di un menu


Dim ObjRagazza As ragazza = New ragazza()


'imposto la proprietà


ObjRagazza.Colore = "Rossi"


'imposto la proprietà di sola scrittuara


ObjRagazza.Tagliati = True


'rilevo le informazioni sulla classe tramite l'interfaccia


Informazioni(ObjRagazza)



Funzione


Private Sub Informazioni(ByVal Iragazza As ICapelli)


MessageBox.Show("Colore: " & Iragazza.Colore & " lunghezza: " & Iragazza.Lunghezza)


Iragazza.Lavaggio()



End Sub




C#


La classe con il codice completo:


//classe che utilizza l'interfaccia


class Ragazza : ICapelli


{


//variabile per la proprietà colore


string mColore;


//variabile per la proprietà lunghezza


string mLunghezza = "Corti";


//variabile per la proprietà tagliati


bool mTagliati = false;


#region ICapelli Membri di



public string Colore


{


get


{


return mColore;


}


set


{


mColore = value;


}


}



public void Lavaggio()


{


//codice da aggiungere


}



public string Lunghezza


{


get


{


if (mTagliati == true)


{


mLunghezza = "Corti";


}


else


{


mLunghezza = "Lunghi";


}


return mLunghezza;


}


}



public bool Tagliati


{


set


{


mTagliati = value;


}


}



#endregion


}




Esempio di utilizzo in una form, nell’evento click di un menu


Ragazza ObjRagazza = new Ragazza();


//imposto la proprietà


ObjRagazza.Colore = "Rossi";


//imposto la proprietà di sola scrittuara


ObjRagazza.Tagliati = true;


//rilevo le informazioni sulla classe tramite l'interfaccia


Informazioni(ObjRagazza);




Funzione


private void Informazioni(ICapelli Iragazza)


{


MessageBox.Show("Colore: " + Iragazza.Colore + " lunghezza: " + Iragazza.Lunghezza);


Iragazza.Lavaggio();



}




Generics


Un tipo generico è un elemento di programmazione singolo in grado di eseguire le funzionalità di vari tipi di dati. Quando si definisce una classe o una routine generica, non è necessario definire una versione distinta per ogni tipo di dati per cui si desidera implementare la funzionalità. Per creare una funzione o classe di tipo generics, occorre utilizzare la parola chiave of (VB.Net) mentre in C# solo l’alias inserito tra i simboli <>.


Di seguito si riporta un esempio di codice in Vb.Net e C#, una classe di tipo generica, che ha una proprietà (anch’essa generica) nell’utilizzo in una form, nel primo caso i valori passati sono di tipo integer mentre nel secondo caso di tipo string.



VB.Net


Classe generica con un valore di tipo T


'Classe di tipo generics


Class Generica(Of T)


' variabile


Private Valore As T


'proprietà


Public Property Elemento() As T


Get


Return Valore


End Get


Set(ByVal Value As T)



Valore = Value


End Set


End Property


End Class


Esempio di codice utilizzato in un click di un menu in una form, nel primo caso viene definito un oggetto della classe generica di tipo integer, per tanto i valori diversi da quel tipo, per esempio di tipo string, generano un errore. Nel secondo caso, invece viene definita un oggetto della classe generica di tipo string.



'creo un oggetto della classe generica


Dim ObjGenerico As New Generica(Of Integer)


'imposto il valore della proprietà


ObjGenerico.Elemento = 1


'non posso impostare valori diverso dal tipo integer


'ObjGenerico.Elemento = "Testo" ' errore


'visualizzo a video il valore della proprietà


MessageBox.Show(ObjGenerico.Elemento)



'creo un oggetto della classe generica che accetta valori string


Dim ObjGenerico2 As New Generica(Of String)


'imposto il valore della proprietà elemento


ObjGenerico2.Elemento = "Emanuele"


'visualizzo a video il valore della proprietà


MessageBox.Show(ObjGenerico2.Elemento)


C#


Classe generica con un valore di tipo T


//Classe di tipo generics


public class Generica<T>


{


//variabile


private T Valore ;


//proprietà


public T Elemento


{


get


{


return Valore;


}


set


{


Valore = value;


}


}



}



Esempio di codice utilizzato in un click di un menu in una form, nel primo caso viene definito un oggetto della classe generica di tipo integer, per tanto i valori diversi da quel tipo, per esempio di tipo string, generano un errore. Nel secondo caso, invece viene definita un oggetto della classe generica di tipo string.


//creo un oggetto della classe generica


Generica<int> ObjGenerica = new Generica<int>();


//imposto il valore della proprietà


ObjGenerica.Elemento = 1;


//non posso impostare valori diverso dal tipo integer


// ObjGenerica.Elemento = "Testo"; // errore


//visualizzo a video il valore della proprietà


MessageBox.Show(ObjGenerica.Elemento.ToString());




//creo un oggetto della classe generica


Generica<string> ObjGenerica2 = new Generica<string>();


//imposto il valore della proprietà elemento


ObjGenerica2.Elemento = "Emanuele";


//Visualizzo a video il valore della proprietà


MessageBox.Show(ObjGenerica2.Elemento);





I commenti permettono di scrivere del testo in modo che il compilatore ignori tali caratteri. Con la nuova versione di .Net 2.0, possiamo utilizzare anche in Visual Basic Net (visto che precedentemente era solo per C#), dei commenti particolari, ossia la possibilità di creare automaticamente una documentazione esterna sottoforma di documento xml, dove tramite appositi tag possiamo fornire informazioni sul tipo in IntelliSense e viene visualizzato anche in visualizzatore oggetti. Il compilatore elabora tutti i tag validi per XML, per elaborare la documentazione xml, utilizzare il parametro /doc.


Di seguito si riporta una tabella relativa ai tag di VB.NET





























<c>


<code>


<example>


<exception>


<include>


<list>


<para>


<param>


<paramref>


<permission>


<remarks>


<returns>


<see>


<seealso>


<summary>


<typeparam>


<value>




Per C#






























<c>


<code>


<example>


<exception>


<include>


<list>


<para>


<param>


<paramref>


<permission>


<remarks>


<returns>


<see>


<seealso>


<summary>


<typeparam>


<tupeparamref>


<value>




Di seguito si riporta un esempio di codice.


VB.Net


''' <summary>


''' metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


''' </summary>


''' <param name="DataNascita"> data di nascita </param>


''' <returns>un valore relativo agli anni</returns>


Public Function Anni(ByVal DataNascita As DateTime) As Integer



Return DateTime.Now.Year - DataNascita.Year



End Function




C#


/// <summary>


/// metodo che restituisce gli anni tramite il passaggio di un valore (data di nascita)


/// </summary>


/// <param name="DataNascita"> data di nascita</param>


/// <returns>un valore relativo agli anni </returns>


public int Anni(DateTime DataNascita)


{



return DateTime.Now.Year - DataNascita.Year;


}



Figura 4.9 – Si nota il testo che appare nel IntelliSense


Nessun commento: