Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - I Costruttori

Guida al Visual Basic .NET

Capitolo 26° - I Costruttori

<< Precedente Prossimo >>
Come si è accennato nelle precedenti lezioni, i costruttori servono a creare un oggetto, un'istanza materiale della classe. Ogni costruttore, poichè ce ne può essere anche più di uno, è sempre dichiarato usando la keyword New e non può essere altrimenti. Si possono passare parametri al costruttore allo stesso modo di come si passano alle normali procedure o funzioni, specificandoli tra parentesi. Il codice scritto nel costruttore viene eseguito prima di ogni altro metodo nella classe, perciò può anche modificare le variabili read-only (in sola lettura), come vedremo in seguito. Anche i moduli possono avere un costruttore e questo viene eseguito prima della procedura Main. Una cosa da tenere bene a mente è che, nonostante New sia eseguito prima di ogni altra istruzione, sia le costanti sia i campi con inizializzatore (ad esempio Dim I As Int32 = 50) sono già stati inizializzati e contengono già il loro valore. Esempio:
Module Module1
    'Classe
    Class Esempio
        'Costante pubblica
        Public Const Costante As Byte = 56
        'Variabile pubblica che non pu? essere modificata
        Public ReadOnly Nome As String
        'Variabile privata
        Private Variabile As Char

        'Costruttore della classe: accetta un parametro
        Sub New(ByVal Nome As String)
            Console.WriteLine("Sto inizializzando un oggetto Esempio...")
            'Le variabili ReadOnly sono assegnabli solo nel
            'costruttore della classe
            Me.Nome = Nome
            Me.Variabile = "c"
        End Sub
    End Class

    'Costruttore del Modulo
    Sub New()
        Console.WriteLine("Sto inizializzando il Modulo...")
    End Sub

    Sub Main()
        Dim E As New Esempio("Ciao")
        E.Nome = "Io"  ' Sbagliato: Nome è ReadOnly
        Console.ReadKey()
    End Sub
End Module 
Quando si fa correre il programma si ha questo output:
Sto inizializzando il Modulo...
Sto inizializzando un oggetto Esempio... 
L'esempio mostra l'ordine in cui vengono eseguiti i costruttori: prima viene inizializzato il modulo, in seguito viene inizializzato l'oggetto E, che occupa la prima linea di codice della procedura Main. È evidente che Main viene eseguita dopo New.


Variabili ReadOnly

Ho parlato prima delle variabili ReadOnly e ho detto che possono solamente essere lette ma non modificate. La domanda che viene spontaneo porsi è: non sarebbe meglio usare una costante? La differenza è più marcata di quanto sembri: le costanti devono essere inizializzate con un valore immutabile, ossia che definisce il programmatore mentre scrive il codice (ad esempio, 1, 2, "Ciao" eccetera); la variabili ReadOnly possono essere impostate nel costruttore, ma, cosa più importante, possono assumere il valore derivante da un'espressione o da una funzione. Ad esempio:
Public Const Data_Creazione_C As Date = Date.Now  'Sbagliato!
Public ReadOnly Data_Creazione_V As Date = Date.Now  ' Giusto 
La prima istruzione genera un errore "Costant expression is required!" ("È richiesta un'espressione costante!"), derivante dal fatto che Date.Now è una funzione e, come tale, il suo valore, pur preso una sola volta, non è costante, ma può variare. Non si pone nessun problema, invece, per le variabili ReadOnly, poichè sono sempre variabili.


Costruttori Shared

I costruttori Shared sono detti costruttori statici e vengono eseguiti solamente quando è creata la prima istanza di una data classe: per questo sono detti anche costruttori di classe o di tipo poichè non appartengono ad ogni singolo oggetto che da quella classe prende la struttura, ma piuttosto alla classe stessa (vedi differenza tra classe e oggetto). Un esempio di una possibile applicazione può essere questo: si sta scrivendo un programma che tiene traccia di ogni errore riportandolo su un file di log, e gli errori vengono gestiti da una classe Errors. Data la struttura dell'applicazione, possono esistere più oggetti di tipo Errors, ma tutti devono condividere un file comune... Come si fa? Costruttore statico! Questo fa in modo che si apra il file di log solamente una volta, ossia quando viene istanziato il primo oggetto Errors. Esempio:
Module Esempio
    Class Errors
        'Variabile statica che rappresenta un oggetto in grado
        'di scrivere su un file
        Public Shared File As IO.StreamWriter

        'Costruttore statico che inizializza l'oggetto StreamWriter
        'Da notare è che un costruttore statico NON può avere
        'parametri: il motivo è semplice. Se li potesse avere
        'e ci fossero più costruttori normali il compilatore
        'non saprebbe cosa fare, poichè Shared Sub New
        'potrebbe avere parametri diversi dagli altri
        Shared Sub New()
            Console.WriteLine("Costruttore statico: sto creando il log...")
            File = New IO.StreamWriter("Errors.log")
        End Sub

        'Questo è il costruttore normale
        Sub New()
            Console.WriteLine("Costruttore normale: sto creando un oggetto...")
        End Sub

        Public Sub WriteLine(ByVal Text As String)
            File.WriteLine(Text)
        End Sub
    End Class

    Sub Main()
        'Qui viene eseguito il costruttore statico e quello normale
        Dim E1 As New Errors
        'Qui solo quello normale
        Dim E2 As New Errors

        E1.WriteLine("Nessun errore")

        Console.ReadKey()
    End Sub
End Module 
L'ouput è:
Costruttore statico: sto creando il log...
Costruttore normale: sto creando un oggetto...
Costruttore normale: sto creando un oggetto... 
Questo esempio evidenzia bene come vengano eseguiti i costruttori: mentre si crea il primo oggetto Errors in assoluto viene eseguito quello statico e in più anche quello normale, per i successivi, invece, solo quello normale. Ovviamente non trovere il file Errors.log con la scritta "Nessun errore" poichè nell'esempio il file non è stato chiuso. Riprenderemo lo stesso discorso con i distruttori.


Costruttori Friend e Private

I costruttori possono essere specificati come Friend e Private proprio come ogni altro membro di classe. Tuttavia l'uso degli specificatori di accesso sui costruttori ha particolari effetti collaterali. Dichiarare un costruttore Private, ad esempio, equivale e imporre che niente possa inizializzare l'oggetto al di fuori della classe stessa: questo caso particolare è stato analizzato nella lezione precedente con i metodi factory statici e serve a rendere obbligatorio l'uso di questi ultimi. Un costruttore Friend invece rende la classe inizializzabile da ogni parte del progetto corrente: se un client esterno utilizzasse la classe importandola da una libreria (vedi oltre) non potrebbe usarne il costruttore.



<< Precedente Prossimo >>
A proposito dell'autore

C#, TypeScript, java, php, EcmaScript (JavaScript), Spring, Hibernate, React, SASS/LESS, jade, python, scikit, node.js, redux, postgres, keras, kubernetes, docker, hexo, etc...