|
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
12.1.1. Shared Access ModifierAlle 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 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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 2010 Broncode Namespace SharedMembersOfAClass Module Client Public Sub Main() Console.WriteLine(Area.Rectangle(3, 4)) Console.WriteLine(Area.Circle(1)) Console.ReadLine() End Sub End ModuleEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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. boven
12.1.2. Classes versus ModulesVorige Area klasse kan worden omgevormd naar module Area. Visual Basic 2010 Broncode 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 ModuleEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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 2010 Broncode Namespace SharedMembersOfAModule Class Client Public Shared Sub Main() Console.WriteLine(Area.Rectangle(3, 4)) Console.WriteLine(Area.Circle(1)) Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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. boven
12.1.3. Constanten als Class MembersEen 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 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 12
3,14159265358979
3,14159265358979 Vergeet ook niet bij constante members van een klasse een gepast access modifier uit te kiezen. boven
12.1.4. Class VariablesNaast 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 2010 Broncode Namespace ClassVariables Class [Class] Public Sub New( ByVal instanceValue As Integer, _ ByVal classValue As Integer) m_InstanceValue = instanceValue m_ClassValue = classValue End Sub Private m_InstanceValue As Integer Private Shared m_ClassValue As Integer Public Overrides Function ToString() As String ToString = "InstanceValue : " & m_InstanceValue & " / " & _ "ClassValue : " & m_ClassValue End Function End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output InstanceValue : 1 / ClassValue : 10
InstanceValue : 2 / ClassValue : 20
InstanceValue : 1 / ClassValue : 20 Zoals je merkt wordt de waarde uit het veld m_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 ). boven
12.1.5. Class ConstructorsOok 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 2010 Broncode 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 Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output Class1 : Shared Sub New()
Class1 : Public Sub New() Visual Basic 2010 Broncode Namespace SharedConstructors Class Class2 : Inherits Class1 Shared Sub New() Console.WriteLine( "Class2 : Shared Sub New()") End Sub Public Sub New() MyBase.New() 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output Class2 : Shared Sub New()
Class1 : Shared Sub New()
Class1 : Public Sub New()
Class2 : Public Sub New() Visual Basic 2010 Broncode Namespace SharedConstructors Class Client3 Public Shared Sub Main() Class1.Test() Class2.Test() Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output Class1 : Shared Sub New()
Class1 : Public Sub Test() Visual Basic 2010 Broncode Namespace SharedConstructors Class Client4 Public Shared Sub Main() Class2.Test() Console.ReadLine() End Sub End ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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. boven
12.1.6. OefeningenOpgave :
Ontwerp de vereiste klasse, om onderstaande clientcode correct te kunnen uitvoeren. Visual Basic 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Console Application Output 3
12 Oplossing : Visual Basic 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Opgave : Ontwerp de vereiste klasse, om onderstaande clientcode correct te kunnen uitvoeren. Visual Basic 2010 Broncode 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
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 2010 Broncode Namespace Excercise2 Class Rectangle Public Sub New( ByVal height As Single, ByVal width As Single) Me.Height = height Me.Width = width End Sub Private m_Height As Single Public Property Height() As Single Get Height = m_Height End Get Set( ByVal value As Single) m_Height = value End Set End Property Private m_Width As Single Public Property Width() As Single Get Width = m_Width End Get Set( ByVal value As Single) m_Width = value End Set End Property 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 ClassEnd NamespaceDownload Visual Basic 2010 Broncode Download Visual C# Sourcecode
Dit artikel is gepubliceerd op zondag 31 juli 2011 op vbvoorbeelden, bezoek de website voor een recente versie van dit artikel of andere artikels.
|