Visual Basic 2012 Voorbeelden
   

visual basic 2012 broncode voorbeelden

Blijf op de hoogte van de recente aanpassingen op vbvoorbeelden!

Microsoft Visual Studio 2012Microsoft Developers Network - Visual BasicMicrosoft .NET Framework

12.1. Class of Shared Members

Print Email Deel op Twitter Deel op Facebook

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.

12.1.1. Shared Access Modifier

Alle members die we tot nu toe in klassen hadden gedefinieerd waren instancemembers : ofwel velden die een toestand bevatten voor een bepaalde instantie (object) van een bepaalde klasse, ofwel implementatiemembers waarbij de implementatie op een bepaalde instantie (object) worden uitgevoerd.
Functions bijvoorbeeld worden gebruikt om een bepaalde (afgeleide) toestand van een instantie (object) op te leveren, procedures worden bijvoorbeeld gebruikt om een bepaalde toestand van een instantie (object) te manipuleren.

Een nieuw soort van members die hier wordt behandeld zijn de "class members", ook wel "static members" of in de context van Visual Basic "shared members" genoemd.

Deze class members zijn niet zozeer aan een bepaald object gerelateerd zoals instance members, maar eerder aan de klasse ("CLASS members") zelf gerelateerd.
Dergelijke members worden gedeeld ("SHARED members") door alle instanties/objecten van die klasse waarin die members zijn gedefinieerd.
Visual Basic 2012 Broncode - Codevoorbeeld 329
Namespace SharedMembersOfAClass
    Class Area
        Public Shared Function Rectangle(ByVal height As Double, _
                                         ByVal width As Double) As Double
            Return height * width
        End Function
        Public Shared Function Circle(ByVal radius As Double) As Double
            Return radius ^ 2 * Math.PI
        End Function
    End Class
End Namespace
In bovenstaande klasse zijn alle members "class/shared members".  Bij implementatiemembers word de access modifier Shared toegevoegd aan de overige signatuur van die member definitie om dit te bekomen.
Deze access modifier (Shared) is als enigste combineerbaar met andere access modifiers (Public, Protected, Private, ...).  Deze access modifier is - in tegenstelling tot de andere access modifiers - enkel van toepassing op members van een klasse.

Een class member kan men aanspreken net zoals een instancemember door de puntnotatie te gebruiken maar deze keer verwijzen naar de klasse zelf in plaats van naar een instantie/object van die klasse.

Men verwijst dus op volgende wijze naar een class member : class_identifier.class_member_identifier(argumentslist)

Ook de Math.PI expressie in bovenstaand voorbeeld is een verwijzing naar een Shared member PI van de Math klasse.  We hoeven hier dus geen object te maken van deze Math klasse vooraleer we de member PI kunnen gebruiken.
Visual Basic 2012 Broncode - Codevoorbeeld 330
Namespace SharedMembersOfAClass
    Module Client
        Public Sub Main()
            Console.WriteLine(Area.Rectangle(3, 4))
            Console.WriteLine(Area.Circle(1))
            '
            Console.ReadLine()
        End Sub
    End Module
End Namespace
Console Application Output
12
3,14159265358979
In een client van klasse Area is het mogelijk maar onzinnig een object te instantiëren van deze klasse.  Geen enkele member is objectgerelateerd, dus een object van deze klasse zou toch geen object specifieke toestand hebben.

Het is mogelijk een classmember aan te roepen via een objectexpressie.  Toch valt dit voor de leesbaarheid af te raden, men krijgt trouwens een warning (maar geen error) wanneer men dit probeert.

12.1.2. Classes versus Modules

Vorige Area klasse kan worden omgevormd naar module Area.
Visual Basic 2012 Broncode - Codevoorbeeld 331
Namespace SharedMembersOfAModule
    Module Area
        Public Function Rectangle(ByVal height As Double, _
                                  ByVal width As Double) As Double
            Return height * width
        End Function
        Public Function Circle(ByVal radius As Double) As Double
            Return radius ^ 2 * Math.PI
        End Function
    End Module
End Namespace
Een module is niet veel meer dan een klasse met enkel Shared members.
Het is niet mogelijk instanties te maken van modules.  Modules kunnen niet overerven of interfaces implementeren.  Modules worden steeds op namespace niveau gedefinieerd en kunnen niet in elkaar genest worden.  Later meer details over interfaces en namespaces.

De members van een module hoeven/kunnen niet als Shared gedefinieerd worden.
Visual Basic 2012 Broncode - Codevoorbeeld 332
Namespace SharedMembersOfAModule
    Class Client
        Public Shared Sub Main()
            Console.WriteLine(Area.Rectangle(3, 4))
            Console.WriteLine(Area.Circle(1))
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
12
3,14159265358979
Anderzijds kunnen we ook de "client" (die we tot nu toe steeds aan de hand van een module hadden gedefinieerd) ook in een klasse uitschrijven.  De Public Sub Main() procedure wordt nu een class member Public Shared Sub Main().

Een belangrijk verschil tussen instance- en classmethods is dat classmethods niet kunnen worden geherdefinieerd.

12.1.3. Constanten als Class Members

Een constante is een onwijzigbare "dataholder" waarvan de inhoud reeds at compiletime is gekend.
Bij een Const declaration moet je immers steeds een toekenningsclausule toevoegen.  De toegekende waarde uit deze toekenningsclausule moet overigens steeds aan de hand van een constante expressie geformuleerd worden.

Als je een constante als member toevoegt aan een klasse, zullen alle instanties van deze klasse dezelfde waarde (die gekend is at compiletime) gebruiken.

Een constante als member is dan ook steeds een class/shared member, zonder dat men dit expliciet in de declaratie kan/moet vermelden.
Visual Basic 2012 Broncode - Codevoorbeeld 333
Namespace ConstantsAreShared
    Class Area
        Public Shared Function Rectangle(ByVal height As Double, _
                                         ByVal width As Double) As Double
            Return height * width
        End Function
        Public Shared Function Circle(ByVal radius As Double) As Double
            Return radius ^ 2 * PI
        End Function
        Public Const PI As Double = Math.PI
    End Class
    Class Example3
        Public Shared Sub Main()
            Console.WriteLine(Area.Rectangle(3, 4))
            Console.WriteLine(Area.Circle(1))
            Console.WriteLine(Area.PI)
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
12
3,14159265358979
3,14159265358979
Vergeet ook niet bij constante members van een klasse een gepast access modifier uit te kiezen.

12.1.4. Class Variables

Naast Shared methods, properties en constanten kan men ook velden als class/shared member declareren, deze worden ook wel "class variables" genoemd.

Deze velden bevatten een toestandswaarde die door alle instanties worden gedeeld, deze waarde zit dan ook slecht één maal in het geheugen.
Visual Basic 2012 Broncode - Codevoorbeeld 334
Namespace ClassVariables
    Class [Class]
        Public Sub New(ByVal instanceValue As Integer, _
                       ByVal classValue As Integer)
            _InstanceValue = instanceValue
            _ClassValue = classValue
        End Sub
        Private _InstanceValue As Integer
        Private Shared _ClassValue As Integer
        Public Overrides Function ToString() As String
            ToString = "InstanceValue : " & _InstanceValue & " / " & _
                        "ClassValue : " & _ClassValue
        End Function
    End Class
End Namespace
Een reserved keyword kan als identifier worden gebruikt zolang je er vierkante haakjes ([...]) rond plaats.  Het valt overigens voor de leesbaarheid af te raden dit te doen.
Visual Basic 2012 Broncode - Codevoorbeeld 335
Namespace ClassVariables
    Class Client
        Public Shared Sub Main()
            Dim object1 As [Class] = New [Class](1, 10)
            Console.WriteLine(object1.ToString())
            '
            Dim object2 As [Class] = New [Class](2, 20)
            Console.WriteLine(object2.ToString())
            '
            Console.WriteLine(object1.ToString())
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
InstanceValue : 1 / ClassValue : 10
InstanceValue : 2 / ClassValue : 20
InstanceValue : 1 / ClassValue : 20
Zoals je merkt wordt de waarde uit het veld _ClassValue gedeeld door alle instanties van de klasse Class.

Het is geen enkel probleem (zoals hierboven ook gedemonstreerd) om een class member aan te roepen/te gebruiken in de implementatie van een instance member.

Het omgekeerde (een instance member aanroepen/gebruiken in de implementatie van een class member) kan echter niet.  Een class member werkt immers onafhankelijk van een instantie, waardoor men geen idee zou hebben waarop ( op welke instantie/object) de aanroep naar de instance member moet worden uitgevoerd.

Een expressie als Me.class member-identifier is mogelijk maar onzinnig, men krijgt hierbij een warning (maar geen error).

12.1.5. Class Constructors

Ook voor constructoren kan de Shared access modifier worden gebruikt.

Dergelijke gedeelde constructoren worden eenmalig uitgevoerd, en dit de eerste keer dat een member wordt gebruikt uit de klasse waarin die constructor is gedefinieerd.
Dit eerste gebruikt van een member kan een impliciete call zijn naar een constructor (zoals bij het gebruik van een objectinitializer (1)), kan een expliciet call zijn naar een constructor (zoals bijvoorbeeld bij het aanroepen van een constructor van de basisklasse) of kan het gebruikt zijn van een classmember.
Visual Basic 2012 Broncode - Codevoorbeeld 336
Namespace SharedConstructors
    Class Class1
        Shared Sub New()
            Console.WriteLine("Class1 : Shared Sub New()")
        End Sub
        Public Sub New()
            Console.WriteLine("Class1 : Public Sub New()")
        End Sub
        Public Shared Sub Test()
            Console.WriteLine("Class1 : Public Sub Test()")
        End Sub
    End Class
    Class Client1
        Public Shared Sub Main()
            Dim object1 As Class1 = New Class1             ' (1)
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Class1 : Shared Sub New()
Class1 : Public Sub New()
Visual Basic 2012 Broncode - Codevoorbeeld 337
Namespace SharedConstructors
    Class Class2 : Inherits Class1
        Shared Sub New()
            Console.WriteLine("Class2 : Shared Sub New()")
        End Sub
        Public Sub New()
            MyBase.New()                                   ' (2)
            Console.WriteLine("Class2 : Public Sub New()")
        End Sub
    End Class
    Class Client2
        Public Shared Sub Main()
            Dim object2 As Class2 = New Class2
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Class2 : Shared Sub New()
Class1 : Shared Sub New()
Class1 : Public Sub New()
Class2 : Public Sub New()
Visual Basic 2012 Broncode - Codevoorbeeld 338
Namespace SharedConstructors
    Class Client3
        Public Shared Sub Main()
            Class1.Test()
            Class2.Test()
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Class1 : Shared Sub New()
Class1 : Public Sub Test()
Visual Basic 2012 Broncode - Codevoorbeeld 339
Namespace SharedConstructors
    Class Client4
        Public Shared Sub Main()
            Class2.Test()
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
Class1 : Shared Sub New()
Class1 : Public Sub Test()
Bemerk dat de shared constructoren hier geen access modifiers als Public, Protected of Private hebben.  Een shared constructor wordt immers steeds impliciet aangeroepen, in tegenstelling tot "gewone" constructoren die ook expliciet aangeroepen kunnen worden in clients als die constructor Public is of in clients en afgeleide klassen als die constructor Protected is.

Gezien shared constructoren steeds impliciet worden aangeroepen, zijn deze steeds parameterloos.

12.1.6. Oefeningen

Opgave :

Ontwerp de vereiste klasse, om onderstaande clientcode correct te kunnen uitvoeren.
Visual Basic 2012 Broncode - Codevoorbeeld 340
Namespace Excercise1
    Class Client
        Public Shared Sub Main()
            Console.WriteLine(Calculation.GetSum(1, 2))
            Console.WriteLine(Calculation.GetProduct(3, 4))
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
3
12
Oplossing :
Visual Basic 2012 Broncode - Codevoorbeeld 341
Namespace Excercise1
    Class Calculation
        Public Shared Function GetSum(ByVal value1 As Integer, _
                                      ByVal value2 As Integer) As Integer
            GetSum = value1 + value2
        End Function
        Public Shared Function GetProduct(ByVal value1 As Integer, _
                                          ByVal value2 As Integer) As Integer
            GetProduct = value1 * value2
        End Function
    End Class
End Namespace
Opgave :
Ontwerp de vereiste klasse, om onderstaande clientcode correct te kunnen uitvoeren.
Visual Basic 2012 Broncode - Codevoorbeeld 342
Namespace Excercise2
    Class Client
        Public Shared Sub Main()
            Dim rectangle1 As Rectangle = New Rectangle(7, 5)
            Dim rectangle2 As Rectangle = New Rectangle(8, 4)
            '
            Console.WriteLine(rectangle1.ToString() = "7 by 5")
            Console.WriteLine(rectangle2.ToString() = "8 by 4")
            '
            Console.WriteLine(rectangle1.IsGreaterThan(rectangle2) = True)
            Console.WriteLine(rectangle2.IsGreaterThan(rectangle1) = False)
            '
            Console.WriteLine(Rectangle.Greatest(rectangle1, rectangle2) Is rectangle1)
            '
            Console.ReadLine()
        End Sub
    End Class
End Namespace
Console Application Output
True
True
True
True
True
"Grootste" wordt gebaseerd op de oppervlakte.  Zorg dat de logica voor het bepalen van de grootste nergens overbodig herhaald wordt.
Oplossing :
Visual Basic 2012 Broncode - Codevoorbeeld 343
Namespace Excercise2
    Class Rectangle
        Public Sub New(ByVal height As Single, ByVal width As Single)
            Me.Height = height
            Me.Width = width
        End Sub
        Public Property Height As Single
        Public Property Width As Single
        Public ReadOnly Property Area() As Double
            Get
                Area = Height * Width
            End Get
        End Property
        Public Function IsGreaterThan(ByVal other As Rectangle) As Boolean
            If Me.Area > other.Area Then IsGreaterThan = True
        End Function
        Public Shared Function Greatest(ByVal rectangle1 As Rectangle, _
                                        ByVal rectangle2 As Rectangle) _
                                                                    As Rectangle
            Greatest = rectangle1
            If rectangle2.IsGreaterThan(rectangle1) Then Greatest = rectangle2
        End Function
        Public Overrides Function ToString() As String
            ToString = Height & " by " & Width
        End Function
    End Class
End Namespace

Dit artikel is gepubliceerd op maandag 15 oktober 2012 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.