Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Guida al Visual Basic .NET - LOverloading

Guida al Visual Basic .NET

Capitolo 31° - LOverloading

<< Precedente Prossimo >>


L'Overloading è la capacità di un linguaggio ad oggetti di poter definire, nella stessa classe, più varianti dello stesso metodo. Per poter eseguire correttamente l'overloading, è che ogni variante del metodo abbia queste caratteristiche:
  • Sia della stessa categoria (procedura O funzione, anzi, per dirla in modo più esplicito: procedura Xor funzione);
  • Abbia lo stesso nome;
  • Abbia signature diversa da tutte le altre varianti. Per coloro che non se lo ricordassero, la signature di un metodo indica il tipo e la quantità dei suoi parametri. Questo è il tratto essenziale che permette di differenziare concretamente una variante dall'altra.
Per fare un esempio, il metodo Console.WriteLine espone ben 18 versioni diverse, che ci consentono di stampare pressoché ogni dato sullo schermo. Fra quelle che non abbiamo mai usato, ce n'è una in particolare che vale la pena di introdurre ora, poiché molto utile e flessibile. Essa prevede un primo parametro di tipo stringa e un secondo ParamArray di oggetti:
Console.WriteLine("stringa", arg0, arg1, arg2, arg3, ...) 
Il primo parametro prende il nome di stringa di formato, poiché specifica il formato in cui i dati costituiti dagli argomenti addizionali dovranno essere visualizzati. All'interno di questa stringa, si possono specificare, oltre ai normali caratteri, dei codici speciali, nella forma "{I}", dove I è un numero compreso tra 0 e il numero di paramtri meno uno: "{I}" viene detto segnaposto e verrà sostituito dal parametro I nella stringa. Ad esempio:
A = 1
B = 3
Console.WriteLine("La somma di {0} e {1} è {2}.", A, B, A + B)
'> "La somma di 1 e 3 è 4." 
Ulteriori informazioni sulle stringhe di formato sono disponibili nel capitolo "Magie con le stringhe".
Ma ora passiamo alla dichiarazione dei metodi in overload. La parola chiave da usare, ovviamente, è Overloads, specificata poco dopo lo scope, e dopo gli eventuali Overridable od Overrides. Le entità che possono essere sottoposte ad overload, oltre ai metodi, sono:
  • Metodi statici
  • Operatori
  • Proprietà
  • Costruttori
  • Distruttori
Anche se gli ultimi due sono sempre metodi - per ora tralasciamo i distruttori, che non abbiamo ancora analizzato - è bene specificare con precisione, perchè a compiti speciali spesso corrispondono comportamenti altrettanto speciali. Ecco un semplicissimo esempio di overload:
Module Module1

    'Restituisce il numero di secondi passati dalla data D a oggi
    Private Function GetElapsed(ByVal D As Date) As Single
        Return (Date.Now - D).TotalSeconds
    End Function

    'Come sopra, ma il parametro è di tipo intero e indica
    'un anno qualsiasi
    Private Function GetElapsed(ByVal Year As Int32) As Single
        'Utilizza Year per costruire un nuovo valore Date
        'e usa la precedente variante del metodo per
        'ottenere il risultato
        Return GetElapsed(New Date(Year, 1, 1))
    End Function

    'Come le due sopra, ma il parametro è di tipo stringa
    'e indica la data
    Private Function GetElapsed(ByVal D As String) As Single
        Return GetElapsed(Date.Parse(D))
    End Function

    Sub Main()
        'GetElapsed viene chiamata con tre tipi di parametri
        'diversi, ma sono tutti leciti
        Dim El1 As Single = GetElapsed(New Date(1987, 12, 4))
        Dim El2 As Single = GetElapsed(1879)
        Dim El3 As Single = GetElapsed("12/12/1991")

        Console.ReadKey()
    End Sub

End Module 
Come avrete notato, nell'esempio precedente non ho usato la keyword Overloads: anche se le regole dicono che i membri in overload vanno segnati, non è sempre necessario farlo. Anzi, molte volte si evita di dichiarare esplicitamente i membri di cui esistono varianti come Overloads. Ci sono varie ragioni per questa pratica: l'overload è scontato se i metodi presentano lo stesso nome, e il compilatore riesce comunque a distinguere tutto nitidamente; inoltre, capita spesso di definire varianti e per rendere il codice più leggibile e meno pesante (anche se i sorgenti in VB tendono ad essere un poco prolissi), si omette Overloads. Tuttavia, esistono casi in cui è assolutamente necessario usare la keyword; eccone un esempio:
Module Module1
    Class Person
        Protected _FirstName, _LastName As String
        Private ReadOnly _BirthDay As Date

        Public Property FirstName() As String
            Get
                Return _FirstName
            End Get
            Set(ByVal Value As String)
                If Value <> "" Then
                    _FirstName = Value
                End If
            End Set
        End Property

        Public Overridable Property LastName() As String
            Get
                Return _LastName
            End Get
            Set(ByVal Value As String)
                If Value <> "" Then
                    _LastName = Value
                End If
            End Set
        End Property

        Public ReadOnly Property BirthDay() As Date
            Get
                Return _BirthDay
            End Get
        End Property

        Public Overridable ReadOnly Property CompleteName() As String
            Get
                Return _FirstName & " " & _LastName
            End Get
        End Property

        'ToString è una funzione definita nella classe
        'System.Object e poiché ogni cosa in .NET
        'deriva da questa classe, &egrae; sempre possibile
        'ridefinire tramite polimorfismo il metodo ToString. 
        'In questo caso ne scriveremo non una, ma due versioni,
        'quindi deve essere dichiarato sia Overrides, perchè
        'sovrascrive System.Object.ToString, sia Overloads,
        'perchè è una versione alternativa di
        'quella che andremo a scrivere tra poco
        Public Overloads Overrides Function ToString() As String
            Return CompleteName
        End Function

        'Questa versione accetta un parametro stringa che assume 
        'la funzione di stringa di formato: il metodo restituirà
        'la frase immessa, sostituendo {F} con FirstName e {L} con 
        'LastName. In questa versione è sufficiente
        'Overloads, dato che non esiste un metodo ToString che 
        'accetti un parametro stringa in System.Object e perciò 
        'non lo potremmo modificare
        Public Overloads Function ToString(ByVal FormatString As String) _
            As String
            Dim Temp As String = FormatString
            'Sostituisce {F} con FirstName
            Temp = Temp.Replace("{F}", _FirstName)
            'Sostituisce {L} con LastName
            Temp = Temp.Replace("{L}", _LastName)

            Return Temp
        End Function

        Sub New(ByVal FirstName As String, ByVal LastName As String, _
            ByVal BirthDay As Date)
            Me.FirstName = FirstName
            Me.LastName = LastName
            Me._BirthDay = BirthDay
        End Sub
    End Class

    Sub Main()
        Dim P As New Person("Mario", "Rossi", Date.Parse("17/07/67"))

        Console.WriteLine(P.ToString)
        '> Mario Rossi
        
        'vbCrLf è una costante che rappresenta il carattere
        '"a capo"
        Console.WriteLine(P.ToString("Nome: {F}" & vbCrLf & "Cognome: {L}"))
        '> Nome: Mario
        '> Cognome: Rossi

        Console.ReadKey()
    End Sub
End Module  
Come mostrato dall'esempio, quando il membro di cui si vogliono definire varianti è sottoposto anche a polimorfismo, è necessario specificare la keyword Overloads, poiché, in caso contrario, il compilatore rintraccerebbe quello stesso membro come diverso e, non potendo esistere membri con lo stesso nome, produrrebbe un errore.
<< Precedente Prossimo >>
A proposito dell'autore

Programmatore e analista .NET 2005/2008/2010 (in particolare C# e VB.NET), anche nell'implementazione Mono per Linux. Conoscenze approfondite di Pascal, PHP, XML, HTML 4.01/5, CSS 2.1/3, Javascript (e jQuery). Conoscenze buone di C, LUA, GML, Ruby, XNA, AJAX e Assembly 68000. Competenze basilari di C++, SQL, Hlsl, Java.