|
Dit artikel is gepubliceerd op woensdag 28 april 2010 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 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 Class
End NamespaceDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Bovenstaand voorbeeld bevat geen compileerfouten. Visual Basic 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 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 Class
End NamespaceDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Visual Basic 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 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 Class
End NamespaceDownload Visual Basic Broncode Bekijk deze Broncode in Visual C#
Visual Basic 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 woensdag 28 april 2010 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
Visual Basic 2008 & 2010 Boeken
Berichten
|