|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
De combinatie van redefinition en overloading kan tot verwarrende code leiden.
Bestudeer onderstaande code, probeer na te gaan of er compileerfouten zouden optreden en zoniet welke de output zou zijn. Visual Basic 2010 Broncode Namespace WithOverloading Class ClassA End Class Class ClassB : Inherits ClassA End Class Class Class1 Public Overridable Sub Test( ByVal classA As ClassA) Console.WriteLine( "C1-CA") End Sub End Class Class Class2 : Inherits Class1 Public Overrides Sub Test( ByVal classA As ClassA) Console.WriteLine( "C2-CA") End Sub Public Overloads Sub Test( ByVal classB As ClassB) Console.WriteLine( "C2-CB") End Sub End Class Class Example Public Shared Sub Main() Dim objectB As ClassB = New ClassB Dim objectA As ClassA = objectB Dim object2 As Class2 = New Class2 Dim object1 As Class1 = object2 object1.Test(objectA) object1.Test(objectB) object2.Test(objectA) object2.Test(objectB) Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Bovenstaand voorbeeld bevat geen compileerfouten. Console Application Output C2-CA
C2-CA
C2-CA
C2-CB Je ziet hoe moeilijk leesbaar bovenstaande clientcode is. Men dient rekening te houden met het statisch type van een expressie door de compiler gebruikt ( in de gevallen van overloading ) en het dynamisch type van een expressie gebruikt voor de binding.
Overloading brengt meestal niets bij aan de uitdrukkingskracht van de taal, al te vaak zorgt het voor verwarrende of op zen minst moeilijk leesbare code. Het gebruik ervan valt dan ook doorgaans af te raden.
In onderstaande versie hebben de twee Test methods elke een eigen identifier gekregen. Visual Basic 2010 Broncode Namespace WithoutOverloading Class ClassA End Class Class ClassB : Inherits ClassA End Class Class Class1 Public Overridable Sub TestClassA( ByVal classA As ClassA) Console.WriteLine( "C1-CA") End Sub End Class Class Class2 : Inherits Class1 Public Overrides Sub TestClassA( ByVal classA As ClassA) Console.WriteLine( "C2-CA") End Sub Public Sub TestClassB( ByVal classB As ClassB) Console.WriteLine( "C2-CB") End Sub End Class Class Example2 Public Shared Sub Main() Dim objectB As ClassB = New ClassB Dim objectA As ClassA = objectB Dim object2 As Class2 = New Class2 Dim object1 As Class1 = object2 object1.TestClassA(objectA) object1.TestClassA(objectB) object2.TestClassA(objectA) object2.TestClassB(objectB) Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output C2-CA
C2-CA
C2-CA
C2-CB Bemerkt hoe eenvoudig het is de output van bovenstaande code te voorspellen. De identifier van de Test method in kwestie geeft meteen aan welke method men uit de publieke interface aanroept. Het is enkele nog een kwestie van het dynamische type van de ontvangerexpressie na te gaan, om te weten welke implementatie aan deze methodcall zal worden gekoppeld. En gezien hier in dit voorbeeld het DTE van de expressies object1 en object2 steeds Class2 is, zal de call naar de method TestClassA steeds gekoppeld worden aan de implementatie voor deze method gedefinieerd in klasse Class2.
Ook aan de uitvoer van volgend voorbeeld is duidelijk dat de overladen versies van SomeFunction niet de best leesbare/voorspelbare code opleveren. Visual Basic 2010 Broncode Namespace OtherExample Class AClass Public Shared Function AFunction( ByVal AArgument As Short) As String AFunction = "Short" End Function Public Shared Function AFunction( ByVal AArgument As Integer) As String AFunction = "Integer" End Function Public Shared Function AFunction( ByVal AArgument As Double) As String AFunction = "Double" End Function End Class Class Example Public Shared Sub Main() Dim aByte As Byte Dim aShort As Short Dim aInteger As Integer Dim aSingle As Single Dim aDouble As Integer Console.WriteLine(AClass.AFunction(aByte)) Console.WriteLine(AClass.AFunction(aByte * aByte)) Console.WriteLine(AClass.AFunction(aByte ^ aByte)) Console.WriteLine(AClass.AFunction(aShort)) Console.WriteLine(AClass.AFunction(aShort * aShort)) Console.WriteLine(AClass.AFunction(aShort ^ aShort)) Console.WriteLine(AClass.AFunction(aInteger)) Console.WriteLine(AClass.AFunction(aInteger * aInteger)) Console.WriteLine(AClass.AFunction(aInteger ^ aInteger)) Console.WriteLine(AClass.AFunction(aSingle)) Console.WriteLine(AClass.AFunction(aSingle * aSingle)) Console.WriteLine(AClass.AFunction(aDouble)) Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output Short
Short
Double
Short
Short
Double
Integer
Integer
Double
Double
Double
Integer Bovenstaande code is verwarrend, men moet bijvoorbeeld weten dat een aInteger ^ aInteger (1) een Double zal opleveren, om te voorspellen dat hier AFunction met Double argument wordt aangeroepen.
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|