Alla base di ogni linguaggio di programmazione orientato agli oggetti c'è il concetto di classe. Chi ha già usato le versioni precedenti di Visual Basic assocerà immediatamente il concetto di classe a quello di modulo di classe. In effetti, le classi di VB .NET mantengono tutte le caratteristiche dei moduli di classe, ma ne aggiungono numerose altre (come verrà evidenziato meglio nelle prossime Lezioni). In prima approssimazione, una classe è una collezione di variabili, metodi e proprietà; è possibile creare una classe usando il costrutto Class:
Class Test
Dim Nome As string
'Altre variabili.
Public Sub VisualizzaNome()
'...
End Sub
End Class
Una classe è anche un tipo, quindi può essere assegnata ad una variabile:
Dim Prova As New Test() 'La variabile Prova contiene un'istanza della classe Test.
E' da notare l'uso della parola chiave New, necessaria perché la variabile che stiamo definendo si riferisce ad un oggetto (come in Visual Basic 6, infatti, le istanze degli oggetti sono create con New). Fatto questo, è possibile utilizzare la classe utilizzando la comune sintassi di Visual Basic. Ad esempio:
Prova.VisualizzaNome()
L'evento Iniziatialize, generato quando si crea un'istanza della classe, non esiste più: al suo posto è possibile definire un costruttore della classe, cioè un metodo che viene automaticamente richiamato quando si crea un'istanza della classe stessa; una delle caratteristiche più importanti del costruttore è che esso consente di specificare le proprietà iniziali della classe (in questo senso è più versatile dell'evento Initialize). Il costruttore è una particolare Sub il cui nome deve obbligatoriamente essere New. Riprendendo l'esempio precedente, vediamo come creare un costruttore per la classe Test:
Class Test
Dim Nome As string
'Altre variabili.
Sub New(ByVal strNome As String)
'Imposta le proprietà iniziali.
Nome = strNome
End Sub
Public Sub VisualizzaNome()
'...
End Sub
End Class
Come possiamo vedere, la routine New prende come argomento la variabile strNome e la assegna alla sua variabile interna Nome. E' possibile definire un oggetto di tipo Test utilizzando il suo costruttore:
Dim Prova As New Test("Marco")
Mentre le Sub e le Function sono rimaste sostanzialmente immutate, la creazione di proprietà di una classe è diversa rispetto alle versioni precedenti. In VB6 si usavano due metodi, Property Set e Property Let, rispettivamente per assegnare e recuperare il valore di una proprietà. In VB .NET, invece, è stato tutto riunito in un unico metodo, che include sia il codice per recuperare sia quello per impostare il valore di una proprietà; ad esempio:
Public Property NomeUtente() As String
Get
Return Nome
End Get
Set(ByVal Value As String)
Nome = Value
End Set
End Property
Come si vede, questa proprietà è composta da due parti: il blocco Get, delimitato da Get... End Get, e il blocco Set (Set... End Set). A parte queste differenze sintattiche, il comportamento dei due blocchi è quello che ci si aspetta: con Get si restituisce il valore della proprietà, mentre con Set si specifica un valore per essa. L'utilizzo di una proprietà così creata rimane lo stesso.
Nella definizione di una routine, oltre a Public o Private, in VB .NET è possibile usare, tra le altre, la nuova parola chiave Protected ; per maggiori informazioni sulle altre parole chiave si consiglia di consultare la Guida in linea di Visual Basic .NET.
Definendo una routine di una classe come Public, essa sarà visibile da tutti le istanze di quella classe; se, invece, si usa la parola chiave Private, tale routine non sarà utilizzabile all'esterno della classe. Ad esempio:
Public Class Test
'...
'...
Public Sub VisualizzaData()
'...
End Sub
Private Function Formatta() As String
'...
End Function
End Class
Dim Prova As New Test()
Prova.VisualizzaData() 'Corretto.
Prova.Formatta() 'Errato: non è possibile accedere alla funzione
Formatta, perché è Private.
Infine, dichiarando una routine della classe Test come Protected, essa sarà visibile a tutte le classi che ereditano da Test (questo concetto verrà chiarito meglio nelle prossime Lezioni, quando si affronteranno i concetti di ereditarietà, polimorfismo e overloading); questa routine non potrà però essere utilizzata dalle istanze della classe. In pratica, Protected equivale a Private, con la differenza che il metodo è visibile anche alle classi che ereditano da quella principale.
Più classi possono essere raggruppate in un unico Namespace. Ad esempio:
Namespace Test
Class Test1
'...
End Class
Class Test2
'...
End Class
End Namespace
Con questo costrutto, per dichiarare un oggetto di tipo Test1 è necessario scrivere, ad esempio:
Dim Prova1 As New Test.Test1()
Analogamente, per oggetti di tipo Test2:
Dim Prova2 As New Test.Test2()
Fatto questo, è possibile accedere ai metodi ed alle proprietà delle classi Test1 e Test2 nel modo consueto.
I namespace sono sempre Public, mentre i componenti all'interno possono essere Public o Friend (impostazioni predefinita). E' possibile definire un namespace dentro un altro, ad esempio:
Namespace N1
Namespace N2
Class Test1
'...
End Class
Class Test2
'...
End Class
End Namespace
End Namespace
Dim Prova1 As New N1.N2.Test1()
Dim Prova2 As New N1.N2.Test2()
Tutte le classi che compongono la piattaforma .NET sono organizzate in namespace. Ad esempio, la classe Form, da cui ereditano tutti i Windows form (argomento della Lezione 8) è raggiungibile nel namespace Windows.System.Forms.Form.
A questo punto si hanno tutti gli strumenti necessari per analizzare le caratteristiche di VB .NET che ne fanno un linguaggio di programmazione orientato agli oggetti: nelle prossime Lezioni parleremo di ereditarietà, polimorfismo ed overloading.