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,.
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
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
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
{
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
'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
'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
'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
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
End Class
Classe secondaria
Class ClasseB
Inherits ClasseA
'stesso nome della variabile della classe base
Public Shadows
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
'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
'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
'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
//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
}
//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
}
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:
Posta un commento