|
Bene bene. Eccoci arrivati al sugo della questione. Le classi, entità alla base di tutto l'edificio del .NET. Già nei primi
capitoli di questa guida ho accennato alle classi, alla loro sintassi e al modo di dichiararle. Per chi non si ricordasse (o non avesse voglia
di lasciare questa magnifica pagina per ritornare indietro nei capitoli), una classe si dichiara semplicemente così:
Class [Nome Classe]
'...
End Class
Con l'atto della dichiarazione, la classe inizia ad esistere all'interno del codice sorgente, cosicchè il programmatore la può
usare in altre parti del listato per gli scopi a causa dei quali è stata creata. Ora che ci stiamo avvicinando sempre più
all'usare le classi nei prossimi programmi, tuttavia, è doveroso ricordare ancora una volta la sostanziale differenza tra dichiarazione
e inizializzazione, tra classe e oggetto, giusto per rinfrescare le memorie più fragili e, lungi dal farvi odiare questo concetto,
per fare in modo che il messaggio penetri:
Module Module1
'Classe che rappresenta un cubo.
'Segue la dichiarazione della classe. Da questo momento
'in poi, potremo usare Cube come tipo per le nostre variabili.
'Notare che una classe si dichiara e basta, non si
'"inizializza", perchè non è qualcosa di concreto,
'è un'astrazione, c'è, esiste in generale.
Class Cube
'Variabile che contiene la lunghezza del lato
Dim SideLength As Single
'Variabile che contiene la densità del cubo, e quindi
'ci dice di che materiale è composto
Dim Density As Single
'Questa procedura imposta i valori del lato e
'della densità
Sub SetData(ByVal SideLengthValue As Single, ByVal DensityValue As Single)
SideLength = SideLengthValue
Density = DensityValue
End Sub
'Questa funzione restituisce l'area di una faccia
Function GetSurfaceArea() As Single
Return (SideLength ^ 2)
End Function
'Questa funzione restituisce il volume del cubo
Function GetVolume() As Single
Return (SideLength ^ 3)
End Function
'Questa funzione restituisce la massa del cubo
Function GetMass() As Single
Return (Density * GetVolume())
End Function
End Class
Sub Main()
'Variabile di tipo Cube, che rappresenta uno specifico cubo
'La riga di codice che segue contiene la dichiarazione
'della variabile A. La dichiarazione di una variabile
'fa sapere al compilatore, ad esempio, di che tipo
'sarà, in quale blocco di codice sarà
'visibile, ma nulla di più.
'Non esiste ancora un oggetto Cube collegato ad A, ma
'potrebbe essere creato in un immediato futuro.
'N.B.: quando si dichiara una variabile di tipo reference,
'viene comunque allocata memoria sullo stack; viene
'infatti creato un puntatore, che punta all'oggetto
'Nothing, il cui valore simbolico è stato
'spiegato precedentemente.
Dim A As Cube
'Ed ecco l'immediato furuto: con la prossima linea di
'codice, creiamo l'oggetto di tipo Cube che verrà
'posto nella variabile A.
A = New Cube
'Quando New è seguito dal nome di una classe, si crea un
'oggetto di quel tipo. Nella fattispecie, in questo momento
'il programma si preoccuperà di richiedere della
'memoria sull'heap managed per allocare i dati relativi
'all'oggetto e di creare un puntatore sullo stack che
'punti a tale oggetto. Esso, inoltre, eseguirà
'il codice contenuto nel costruttore. New, infatti,
'è uno speciale tipo di procedura, detta
'Costruttore, di cui parlerò approfonditamente
'in seguito
'Come per le strutture, i membri di classe sono accessibili
'tramite l'operatore punto ".". Ora imposto le variabili
'contenute in A per rappresentare un cubo di alluminio
'(densità 2700 Kg/m3) di 1.5m di lato
A.SetData(1.5, 2700)
Console.WriteLine("Superficie faccia: " & A.GetSurfaceArea() & " m2")
Console.WriteLine("Volume: " & A.GetVolume() & " m3")
Console.WriteLine("Massa: " & A.GetMass() & " Kg")
'Pesa quasi una tonnellata!!
Console.ReadKey()
End Sub
End Module
In questo esempio ho usato una semplice classe che rappresenta un cubo di una certa dimensione e di un certo materiale. Tale classe espone
quattro funzioni, che servono per ottenere informazioni o impostare valori. C'è un preciso motivo per cui non ho usato direttamente
le due variabili accedendovi con l'operatore punto, e lo spiegherò a breve nella prossima lezione. Quindi, tali funzioni sono membri
di classe e, soprattutto, funzioni di istanza. Questo lemma non dovrebbe suonarvi nuovo: gli oggetti, infatti, sono istanze (copie
materiali, concrete) di classi (astrazioni). Anche questo concetto è molto importante: il fatto che siano "di istanza" significa che
possono essere richiamate ed usate solo da un oggetto. Per farvi capire, non si possono invocare con questa sintassi:
Cube.GetVolume()
ma solo passando attraverso un'istanza:
Dim B As New Cube
'...
B.GetVolume()
E questo, tra l'altro, è abbastanza banale: infatti, come sarebbe possibile calcolare area, volume e massa se non si disponesse della
misura della lunghezza del lato e quella della densità? È ovvio che ogni cubo ha le sue proprie misure, e il concetto generale di
"cubo" non ci dice niente su queste informazioni.
Un semplice costruttore
Anche se entreremo nel dettaglio solo più in là, è necessario per i prossimi esempi che sappiate come funziona un
costruttore, anche molto semplice. Esso viene dichiarato come una normale procedura, ma si deve sempre usare come nome "New":
Sub New([parametri])
'codice
End Sub
Qualora non si specificasse nessun costruttore, il compilatore ne creerà uno nuovo senza parametri, che equivale al seguente:
Sub New()
End Sub
Il codice presente nel corpo del costruttore viene eseguito in una delle prime fasi della creazione dell'oggetto, appena dopo che questo
è statao fisicamente collocato nella memoria (ma, badate bene, non è la prima istruzione ad essere eseguita dopo la creazione).
Lo scopo di tale codice consiste nell'inizializzare variabili di tipo reference prima solo dichiarate, attribuire valori alle variabili value,
eseguire operazioni di preparazione all'uso di risorse esterne, eccetera... Insomma, serve a spianare la strada all'uso della classe.
In questo caso, l'uso che ne faremo è molto ridotto e, non vorrei dirlo, quasi marginale, ma è l'unico compito possibile e
utile in questo contesto: daremo al costruttore il compito di inizializzare SideLength e Density.
Module Module1
Class Cube
Dim SideLength As Single
Dim Density As Single
'Quasi uguale a SetData
Sub New(ByVal SideLengthValue As Single, ByVal DensityValue As Single)
SideLength = SideLengthValue
Density = DensityValue
End Sub
Function GetSurfaceArea() As Single
Return (SideLength ^ 2)
End Function
Function GetVolume() As Single
Return (SideLength ^ 3)
End Function
Function GetMass() As Single
Return (Density * GetVolume())
End Function
End Class
Sub Main()
'Questa è una sintassi più concisa che equivale a:
'Dim A As Cube
'A = New Cube(2700, 1.5)
'Tra parentesi vanno passati i parametri richiesti dal
'costruttore
Dim A As New Cube(2700, 1.5)
Console.WriteLine("Superficie faccia: " & A.GetSurfaceArea() & " m2")
Console.WriteLine("Volume: " & A.GetVolume() & " m3")
Console.WriteLine("Massa: " & A.GetMass() & " Kg")
Console.ReadKey()
End Sub
End Module
Una nota sulle Strutture
Anche le strutture, come le classi, possono esporre procedure e funzioni, e questo non è strano. Esse, inoltre, possono esporre anche costruttori...
e questo dovrebbe apparirvi strano. Infatti, ho appena illustrato l'importanza dei costruttori nell'istanziare oggetti, quindi tipi reference,
mentre le strutture sono palesemente tipi value. Il conflitto si risolve con una soluzione molto semplice: i costruttori dichiarati nelle
strutture possono essere usati esattamente come per le classi, ma il loro compito è solo quello di inizializzare campi e richiamare
risorse, poiché una variabile di tipo strutturato viene creata sullo stack all'atto della sua dichiarazione.
Module Module1
Structure Cube
Dim SideLength As Single
Dim Density As Single
Sub New(ByVal SideLengthValue As Single, ByVal DensityValue As Single)
SideLength = SideLengthValue
Density = DensityValue
End Sub
Function GetSurfaceArea() As Single
Return (SideLength ^ 2)
End Function
Function GetVolume() As Single
Return (SideLength ^ 3)
End Function
Function GetMass() As Single
Return (Density * GetVolume())
End Function
End Structure
Sub Main()
'Questo codice
Dim A As New Cube(2700, 1.5)
'Equivale a questo
Dim B As Cube
B.SideLength = 1.5
B.Density = 2700
'A e B sono uguali
Console.ReadKey()
End Sub
End Module
|
|