Casino online











Mercato forex






A31. Overloading


L'overloading è la capacità di un linguaggio ad oggetti di ridefinire più versioni dello stesso metodo con signature differenti nella stessa classe. Ad esempio, la procedura WriteLine della classe console presenta ben 18 versioni differenti, a seconda del parametro che gli si passa: può infatti accettare stringhe, numeri, date ma può anche utilizzare più di un parametro.


Overloads

In questo ultimo caso, si specifica come prima una stringa di formato e come successivi argomenti quelli che devono esservi inseriti. Una strina di formato potrebbe essere "Ciao {0}, io sono {1}!", dove in {0} sarà sostituito il primo parametro successivo alla stringa di formato e in {1} il secondo. Questo codice:
Console.WriteLine("Ciao {0}, io sono {1}!", "Utente", "Computer") 
Produrrà questo output:
Ciao Utente, io sono Computer! 
Ma ora passiamo alla dichiarazione dei membri in overload. La keyword da usare, ovviamente, è Overloads e si può utilizzare solamente con metodi o proprietà, poichè solo questi possono accettare, e quindi variare, parametri. La sintassi è questa:
Class [Nome classe]
    Overloads [Sub/Function/Property]([Elenco parametri])
        'Corpo del metodo
    End [Sub/Function/Property]
    Overloads [Sub/Function/Property]([Elenco parametri diverso])
        'Corpo del metodo
    End [Sub/Function/Property]
End Class 
Public Overloads Sub Show(ByVal N As Double)
  Console.WriteLine("Numero: " & N)
End Sub

Public Overloads Sub Show(ByVal S As String)
  Console.WriteLine("Stringa: " & S)
End Sub

Public Overloads Sub Show(ByVal N As Double, ByVal S As String)
  Console.WriteLine("Numero (" & N & ") e stringa (" & S & ")")
End Sub
'...

Show(3.124)
'> Numero: 3.124
Show("Ciao")
'> Stringa: Ciao
Show(1920, "Ciao")
'> Numero (1920) e stringa (Ciao) 
L'esempio mostra gli output rispettivi alle diverse chiamate a procedura: sarà il compilatore a "scegliere" quale sarà la più opportuna sulla base del numero e/o del tipo di paramtri passati. Cosa importante da sottolineare è che non si possono definire due overloads di funzioni che differiscono solo per il tipo restituito. Anche gli operatori, i metodi statici e i costruttori possono subire overload, ma nel caso dei costruttoi NON viene usata la parola riservata Overloads. È poi possibile trovare metodi modificati con polimorfismo e overloading insieme:
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, è 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 si vede, ora abbiamo due versioni modificate di ToString nella classe Person: la prima, senza parametri, sovrascrive quella ereditata da System.Object, mentre la seconda, con un parametro, costituisce una versione alternativa della prima. Di solito si ridefinisce la funzione ToString nelle nuove classi che vengono scritte, ma non è nè una convenzione nè un obbligo. Tuttavia, se non venisse modificata con il polimorfismo, ToString restituirebbe comunque un valore, ossia il nome completo della classe a cui appartiene: ad esempio, il mio progetto si chiama "App Prove Console", quindi richiamando tale metodo non ridefinito all'interno della classe Person, avrò come output:
App_Prove_Console.Module1+Person 
Il "+" serve per separare il nome della classe dal nome del tipo in cui è contenuto: si può ottenere questo valore anche facendo ricorso alla proprietà FullName di System.Type nell'ambito della Reflection, ma lo vedremo in seguito.




 

The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.