|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
We vertrekken van een collectietype Persons die een collectie van objecten van een item type Person kan beheren. Visual Basic 2010 Broncode Class Person Private m_Name As String Public Property Name() As String Get Name = m_Name End Get Set( ByVal value As String) m_Name = value End Set End PropertyEnd ClassClass Persons Protected m_Items As Person() Default Public ReadOnly Property Item( ByVal index As Integer) As Person Get Item = m_Items(index) End Get End Property Protected m_Count As Integer Public ReadOnly Property Count() As Integer Get Count = m_Count End Get End Property Public Sub Add( ByVal person As Person) ReDim Preserve m_Items(Count) m_Items(Count) = person m_Count += 1 End SubEnd ClassDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Naderhand wensen we een gespecialiseerd type van Persons te creëren, namelijk een specialisatie waar het ook mogelijk is een Person item uit de collectie op te vragen via een Name.
We beslissen hiervoor een afgeleide klasse QueryablePersons te maken, waar we de members van Persons aanvullen met een extra member Item.
Dat we Item als identifier voor deze member kiezen is logisch, het gaat tenslotte ook over een member die een Item oplevert van de collectie in Person objectvorm.
Van de basisklasse Persons erven we echter reeds een Item over. Om ervoor te zorgen dat een aanroep naar deze members Item ondubbelzinnig is ( duidelijk welke Item wordt aangeroepen ), moeten we een verschil maken in de argumenten. Visual Basic 2010 Broncode Class QueryablePersons : Inherits Persons Default Public Overloads ReadOnly Property Item( _ ByVal name As String) As Person Get Dim index As Integer, found As Boolean Do While index < Count AndAlso Not found If m_Items(index).Name = name Then Item = m_Items(index) found = True Else index += 1 End If Loop End Get End PropertyEnd ClassModule Client Sub Main() Dim person1 As Person = New Person person1.Name = "John" Dim person2 As Person = New Person person2.Name = "Jane" Dim queryablePersons1 As QueryablePersons = New QueryablePersons queryablePersons1.Add(person1) queryablePersons1.Add(person2) Console.WriteLine(queryablePersons1.Item(1) Is person2) Console.WriteLine(queryablePersons1.Item( "Jane") Is person2) Console.WriteLine(queryablePersons1.Item( "Jane").Name = "Jane") Console.ReadLine() End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output True
True
True Meerder members met dezelfde naam ( in dezelfde klasse ) kan door "method overloading" te gebruiken.
Item ( met Integer argument ) die hier in QueryablePersons wordt overgeërfd van Persons wordt hier overladen met een extra versie van Item ( met String argument ).
In het geval dat men een method die wordt overgeërfd overlaad, MOET men hierbij het Overloads keyword te plaatsen. Doet men dit niet dan bekomt men hier "shadowing", wat niet hetzelfde is ( niet hetzelfde effect heeft ) als "overloading". Shadowing wordt pas verderop in de leerstof behandeld, maar er kan alvast gesteld worden dat shadowing beter te vermijden valt.
Bij overloading van een member die in de klasse zelf gedefinieerd is, is het Overloads keyword niet verplicht, maar mag het gebruikt worden.
De compiler zal bij een aanroep naar deze Item property de best passende versie uitkiezen gebaseerd op de argumenten. Geeft men bijvoorbeeld een Integer argumentwaarde op (1) dan wordt dit beschouwd als een aanroep naar Item uit Persons. Geeft men een String argument door bij de aanroep naar Item dan zal de compiler dit beschouwen als een aanroep naar Item gedefinieerd in QueryablePersons.
Hoe verschillende versies van een method of property van elkaar moeten verschillen om nog steeds voor de compiler duidelijk te houden welke versie je aanroept is bepaald in de "overload-resolution" van het "metamodel" van de gebruikte taal. In Visual Basic kunnen we verschillende versies creëren van een method door een verschil te maken in datatypes van de argumenten, aantal argumenten en volgorde van de datatypes van argumenten.
Wees zuinig met het gebruik van overloading in uw eigen klassen, in combinatie met inheritance kan dit tot uiterst moeilijk leesbare en voorspelbare code leiden. Later meer over dit probleem. 9.12.1. OefeningOpgave :
Schrijf een klasse die je kan gebruiken om Counter objecten van te creëren. Voor dergelijk counter object moet je de waarde enkel kunnen opvragen. Voorzie ook methods om de waarde te verhogen en te verlagen. De verhoog- en verlaag stapwaarde mag hier steeds 1 zijn.
Schrijf ook een klasse die bruikbaar is om SpecialCounter objecten van te creëren. Deze objecten dienen net als Counter objecten over een waarde te kunnen beschikken, die deze keer ook moet kunnen worden ingesteld. Bijkomend moet het bij SpecialCounter objecten niet alleen mogelijk zijn met gelijke methods als van Counter objecten de waarde met 1 te verhogen of te verlagen, maar het moet ook mogelijk zijn met extra ( vergelijkbare ) methods de waarde met een specifiek opgegeven waarde te verhogen of te verlagen. Oplossing : Visual Basic 2010 Broncode Class Counter Protected m_Value As Integer Public Function GetValue() As Integer GetValue = m_Value End Function Public Sub Raise() m_Value += 1 End Sub Public Sub Lower() m_Value -= 1 End SubEnd ClassClass SpecialCounter : Inherits Counter Public Sub SetValue( ByVal value As Integer) m_Value = value End Sub Public Overloads Sub Raise( ByVal stapValue As Integer) m_Value += stapValue End Sub Public Overloads Sub Lower( ByVal stapValue As Integer) m_Value -= stapValue End SubEnd ClassModule ExerciseSolution Sub Main() Dim counter1 As Counter = New Counter Console.WriteLine(counter1.GetValue() = 0) counter1.Raise() Console.WriteLine(counter1.GetValue() = 1) counter1.Raise() Console.WriteLine(counter1.GetValue() = 2) counter1.Lower() Console.WriteLine(counter1.GetValue() = 1) counter1.Lower() Console.WriteLine(counter1.GetValue() = 0) Dim specialCounter1 As SpecialCounter = New SpecialCounter Console.WriteLine(specialCounter1.GetValue() = 0) specialCounter1.SetValue(10) Console.WriteLine(specialCounter1.GetValue() = 10) specialCounter1.Raise() Console.WriteLine(specialCounter1.GetValue() = 11) specialCounter1.Raise() Console.WriteLine(specialCounter1.GetValue() = 12) specialCounter1.Lower() Console.WriteLine(specialCounter1.GetValue() = 11) specialCounter1.Lower() Console.WriteLine(specialCounter1.GetValue() = 10) specialCounter1.Raise(5) Console.WriteLine(specialCounter1.GetValue() = 15) specialCounter1.Lower(8) Console.WriteLine(specialCounter1.GetValue() = 7) Console.ReadLine() End SubEnd ModuleDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output True
True
True
True
True
True
True
True
True
True
True
True
True
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|