Hoofdstuk 5 – Object Based Programmeren Inleiding Abstract type Time implementeren via een klasse Klasse Scope Toegang tot members Initialiseren van klasse-objecten: constructoren Gebruik van overladen van constructoren Eigenschappen Compositie: Objecten als instantievariabelen van andere klasses Gebruik van “me” Garbage Collection Gedeelde klasse members Const en ReadOnly members Data abstractie en Information Hiding Hergebruik van software Namespaces and Assemblies Visual Basic.NET
5.1 Inleiding Alles in .NET is een object Instanties van een klasse Een literal zoals 7 of “Welcome” Een klasse kan ook handelen als een object Object State : attributen en properties Gedrag : methodes en events Interface : toegang tot object’s data en gedrag vanuit applicatie Identity : gegeven door systeem (CLR) Klassen : voor de creatie van een ADT(Abstract Data Type) Inkapselen Overerving Polymorfisme 7 is een object. Ik dan daar methodes van aanroepen zoals 7.gettype en 7.tostring.toupper of 7.GetType() retourneert system.int32(is het onderliggende .Net datattype voor de VB integer) State : attribuut (=module level variabele binnen een klasse), properties (property routines) De state verandert continu en is een functie van de tijd. Bvb een wagen is een object. Soms rij ik in de avondspitst aan 20 km/uur als ik op de Brusselse ring in de file zit, of als ik de ring voorbij ben aan 120km/uur. Methode : versnel; event : draai aan de knop voor de lichten. identity : de runtime moet alle objecten uniek kunnen identificeren. Vergelijkbaar met een paspoort voor de mens. Je kan van een object zeggen : ik leef, dus ik ben. Het id de identiteit die toelaat 2 objecten van mekaar te onderscheiden. Het is de runtime die de objecten creëert en ze dan een identiteit en een levenscyclus geeft. GetHashCode : stelt voor een stuk de unieke identiteit voor. Programmeereenheid in VB.NET is de klasse (soms worden ook modules geschreven). Programmeereenheid in niet object-georiënteerde talen is de functie (cfr. Procedures in VB). Klasse = door de progammeur gedefinieerd type. Het is een ADT : het laat toe speciale datatypes te creëeren die hun implementatie voor de gebruiker verbergen. OOP objecten comminiceren met mekaar door het aanroepen van mekaars methoden. Het kan zijn dat een methode van 1 object de methoden van andere objecten aanroept., ... Alle objecten zijn ingekapseld : geen van de objecten hoeft iets te weten over de inwendige structuur van de overige objecten. Dit maakt de programma's minder complex en zorgt voor een betere inwendige samenhang of cohesie. Veel objecten gebruiken dezelfde methods. Om deze niet binnen ieder object te hoeven beschrijven , kan een object gedefinieerd worden als een subklasse van een ander object. = Inheritance (Overerving). D.i. Men kan een nieuw object definieren op basis van een bestaand object en dat object bevat dan dezelfde eigenschappen en methoden. En je kan dan een aantal nieuwe toevoegen. Vb een student en werknemer erven van persoon. Als een programma de methode GetPhoneNumber aanroept in de subklasse student dan wordt de methiode van de klasse werknemer aangeroepen. Als de eisen van de applicatie zo zijn dat de tel van studenten op een andere manier verkregen moeten worden dan deze van personen dan krijgt de subklasse student zijn eigen methode getphonenumber. Deze wordt dan toegepast als de applicatie een telefoonnummer opvraagt van en student. = Polymorphisme (polymorf betekent veelvormig, dezelfde methode bestaat in veel vormen). Veel objecten kunnen methoden met dezelfde naam hebben, toch kan de methode zich in elk object anders gedragen. Zo kan bvb de operator + zowel met integers als met strings gebruikt worden, toch zullen verschillende bewerkingen uitgevoerd worden. Visual Basic.NET
5.2 Implementatie van klasse CTime Klasse CTIME en een module modTimeTest. De klasse Ctime bevat alle informatie nodig voor de voorstelling van de tijd. ModTimeTest bevat een main procedure , die gebruik maakt van een instantie van de klasse ctime. new : constructor setTime : instellen van de tijd. Input 3 parameters ToUniversalString : geeft string terug met universele tijd : 13:30:17 ToStandardString : geeft string terug met standard tijd 1:30:17 PM Visual Basic.NET
5.2 Implementatie van klasse CTime 1 ' CTime.vb 2 ' Represents time in 24-hour format. 3 4 Class CTime 5 Inherits Object 6 7 ' declare Integer instance values for hour, minute and second 8 Private mHour As Integer ' 0 - 23 9 Private mMinute As Integer ' 0 - 59 10 Private mSecond As Integer ' 0 - 59 11 12 ' Method New is the CTime constructor method, which initializes 13 ' instance variables to zero 14 Public Sub New() 15 SetTime(0, 0, 0) 16 End Sub ' New 17 18 ' set new time value using universal time; 19 ' perform validity checks on data; 20 ' set invalid values to zero 21 Public Sub SetTime(ByVal hourValue As Integer, _ 22 ByVal minuteValue As Integer, ByVal secondValue As Integer) 23 24 ' check if hour is between 0 and 23, then set hour 25 If (hourValue >= 0 AndAlso hourValue < 24) Then 26 mHour = hourValue 27 Else 28 mHour = 0 29 End If 30 31 ' check if minute is between 0 and 59, then set minute 32 If (minuteValue >= 0 AndAlso minuteValue < 60) Then 33 mMinute = minuteValue 34 Else 35 mMinute = 0 36 End If CTime class definition. Erft van klasse Object Class CTime inherits existing pieces of class Object. de New constructor Om een klasse toe te voegen aan een project, kies Project > Add Class. Geef de naam van de klasse op in het tekstveld Name en klik op de Open knop. De naam van de klasse (met .vb extensie) verschijnt in de Solution Explorer onder de naam van het project. Klasse CTime: wordt gebruikt om een specifieke tijd te representeren GEEN applicatieklasse, kan dus niet uitgevoerd worden! Lijn 4-5: begin van de klassedefinitie – klasse CTime erft van klasse Object (uit namespace System). Wordt zo vermeld in dit hoofdstuk, maar overerving van Object gebeurt ook impliciet Lijn 4 en 75 lijnen de body van de klasse CTime af (keywords Class en End Class) Lijn 8-10: declaratie van 3 Integer instantievariabelen mHour, mMinute en mSecond. De toegangsmethode is Private want deze zijn enkel toegankelijk voor members van de klasse (hidden data). De gebruikers van de klas zijn niet geinteresseerd in hoe de data in de klasse wordt voorgesteld. De klasse zou de tijd ook kunnen voorstellen als 1 getal : het totaal aantal seconden. Zelf als de representatie intern zou wijzigen. Dan nog zouden de gebruikers van de klasse dezelfde Public methodes kunnen gebruiken en hetzelfde resultaat bekomen. (inkapseling) Lijn 14-16: Public methode New (constructor – initialiseert de instantievariabelen op 0). Dit verzekert dat het object in een consistente status gecreeerd wordt nl. Alle waarden van de instance variabelen zijn geldige waarden. New is de vaste naam voor ELKE constructor, zelfs al zijn er meerdere in 1 klasse (elk met unieke parameters) Lijn 21-45: Public methode SetTime . Gebruikt 3 Integer argumenten om de tijd in te stellen. De waarden worden eerst gecontroleerd en indien ze niet voldoen, krijgen de instantievariabelen defaultwaarde 0. Hierdoor is object steeds in een consistente staat Visual Basic.NET
Class CTime inherits existing pieces of class Object. 38 ' check if second is between 0 and 59, then set second 39 If (secondValue >= 0 AndAlso secondValue < 60) Then 40 mSecond = secondValue 41 Else 42 mSecond = 0 43 End If 44 45 End Sub ' SetTime 46 47 ' convert String to universal-time format 48 Public Function ToUniversalString() As String 49 Return String.Format("{0}:{1:D2}:{2:D2}", _ 50 mHour, mMinute, mSecond) 51 End Function ' ToUniversalString 52 53 ' convert to String in standard-time format 54 Public Function ToStandardString() As String 55 Dim suffix As String = " PM" 56 Dim format As String = "{0}:{1:D2}:{2:D2}" 57 Dim standardHour As Integer 58 59 ' determine whether time is AM or PM 60 If mHour < 12 Then 61 suffix = " AM" 62 End If 63 64 ' convert from universal-time format to standard-time format 65 If (mHour = 12 OrElse mHour = 0) Then 66 standardHour = 12 67 Else 68 standardHour = mHour Mod 12 69 End If 70 71 Return String.Format(format, standardHour, mMinute, _ 72 mSecond) & suffix 73 End Function ' ToStandardString 74 End Class ' CTime Class CTime inherits existing pieces of class Object. Lijn 48-51: Public methode ToUniversalString. Deze methode heeft geen argumenten, maar geeft een String terug met de universele tijd erin (vb. 13u30’07” wordt 13:30:07) maakt gebruik van de format string “{0}:{1:D2}:{2:D2}” die aangeeft dat argument 0 het default formaat moet aannemen en argumenten 1 en 2 het formaat D2 (decimaal getal met basis 10 en gebruik makend van 2 cijfers). De “:” wordt letterlijk overgenomen. Lijn 54-73: Public methode ToStandardString heeft geen argumenten, maar geeft een String terug met de standaard tijd erin (vb. 13u30’07” wordt 1:30:07 PM) ook hier wordt gebruik gemaakt van de methode Format van de klasse String om de minuten en seconden als 2 cijfers te tonen Visual Basic.NET
Class CTime inherits existing pieces of class Object. 1 ' TimeTest.vb 2 ' Demonstrating class CTime. 3 4 Imports System.Windows.Forms 5 6 Module modTimeTest 7 8 Sub Main() 9 Dim time As New CTime() ' call CTime constructor 10 Dim output As String 11 12 output = "The initial universal times is: " & _ 13 time.ToUniversalString() & vbCrLf & _ 14 "The initial standard time is: " & _ 15 time.ToStandardString() 16 17 time.SetTime(13, 27, 6) ' set time with valid settings 18 19 output &= vbCrLf & vbCrLf & _ 20 "Universal time after setTime is: " & _ 21 time.ToUniversalString() & vbCrLf & _ 22 "Standard time after setTime is: " & _ 23 time.ToStandardString() 24 25 time.SetTime(99, 99, 99) ' set time with invalid settings 26 27 output &= vbCrLf & vbCrLf & _ 28 "After attempting invalid settings: " & vbCrLf & _ 29 "Universal time: " & time.ToUniversalString() & _ 30 vbCrLf & "Standard time: " & time.ToStandardString() 31 32 MessageBox.Show(output, "Testing Class CTime") 33 End Sub ' Main 34 35 End Module ' modTimeTest Class CTime inherits existing pieces of class Object. Module modTimeTest maakt gebruik van een instantie van CTime gedraagt zich als een applicatieklasse Nota: klasse CTime moet niet via Imports worden geïmporteerd, aangezien deze in dezelfde namespace zit als TimeTest aangezien er geen namespace vermeld werd, is CTime in de default namespace terechtgekomen, zijnde de directory van het project aangezien TimeTest tot hetzelfde project behoort, zit deze module in dezelfde directory en dus deze namespace Lijn 9: declaratie en initialisatie van een instantie time van de klasse CTime uitbreidbaarheid van de taal door het maken van nieuwe types Lijn 10: String referentie output die de String met de resultaten zal bevatten die dan in een Messagebox zullen getoond worden Lijn 12-15: oproep van de methodes ToUniversalTime en ToStandardTime van CTime om de tijd in beide formaten in de output te krijgen Lijn 17: time wordt ingesteld op 13u27’06” via de SetTime methode van CTime die 3 geldige argumenten meekrijgt Lijn 19-23: cfr lijn 12-15 maar nu met de nieuwe waarde van time Lijn 25: cfr lijn 17, maar nu met ongeldige argumenten Lijn 27-30: cfr lijn 12-15 maar nu met de nieuwe waarde van time. Aangezien de argumenten ongeldig waren, is de tijd ingesteld op de defaultwaarde middernacht Lijn 32: toont de Messagebox met de resultaten Visual Basic.NET
5.2 Implementatie van klasse CTime Object declaratie en Instantiatie Intrinsic (klasse als een type) “Welcome to .NET” 200 Als instantie van een klasse (klasse als een factory) Dim objRandom As Random ‘creatie van object variabele objRandom = New Random() ‘creatie van instantie van klasse,d.i. van object Of Dim objRandom As New Random() Of Dim objRandom As Random = New Random() De klasse wordt als object gebruikt (klasse als een utility) Console.writeline Image.FromFile Creatie van object bestaat uit 2 stappen creatie van object variabele Creatie van een instantie van de klasse : creatie van het object Het resultaat is dat we dan een nieuwe instantie van het object hebben, klaar om te gebruiken. Om met ons nieuw object te interageren, gebruiken we de variabele die we gedeclareerd hebben; De variabele bevat een referentie naar het object. Je kan de 2 ook combineren tot 1 statement : die dan een variabele declareert en een instantie van het object aanmaakt. Dit is een flexibele manier van werken en is heel bruikbaar wanneer we werken met inheritance of meerdere interfaces. We kunnen dan een variabele declareren van 1 datatype, een interface, en dan een instantie van object aanmaken gebaseerd op een klasse die de interface implementeert. Visual Basic.NET
5.2 Implementatie van klasse CTime Creatie van een klasse Project > Add Class Opent code venster Objecten zijn instanties van een specifieke template : een klasse. De klasse bevat de code, die het gedrag van zijn objecten definieert EN de instance variabelen die de data van het object bevatten. Klassen worden gecreeerd adhv Class keyword en bevatten de definitie (declaratie) en implementatie (code) voor variabelen, methoden, properties en events. Elk object van die klasse heeft dezelfde methodes, properties en events en zijn eigen set van data, gedefinieerd door de variabelen in de klasse. Een klasse wordt opgeslaan in een .vb file. In principe zou je in 1 vb file meerdere klasses kunnen opslaan maar dit wordt niet gedaan. Maak een file per klasse. Opm : Alle VB.NET source files hebben extensie .vb, onafhankelijk van zijn type (form, klasse, module,...). In feite zijn alle formulieren, klassen, modules,controls die we toevoegen aan ons project eigenlijk class modules – ze zijn juist een specifiek type van een klasse die voorzien in een bepaald gedrag. Typisch, dit gedrag komt vanuit een andere klasse via inheritance. Visual Basic.NET
5.2 Implementatie van klasse CTime Nu kunnen we de klasse definieren Member variabelen Methodes Properties Events Visual Basic.NET
5.3 De Scope van een klasse Instance variabelen en methodes (members genaamd) Binnen de klasse (class-scope) Toegankelijk in alle methodes via de naam Buiten de klasse (vanuit een applicatie) Enkel de Public(Friend, Protected) class members zijn toegankelijk via een “handle” (ObjectReferenceName.memberName) Variabelen gedeclareerd binnen een methode (block-scope) Enkel toegankelijk binnen die methode Een variabele met block scope kan dezelfde naam hebben als variabele met class-scope => om toch toegang te hebben tot class scope variabele gebruik je dan keyword Me en de dot operator Binnen een klasse hebben alle instance variabelen en methodes class-scope. Dit betekent dat ze kunnen worden gebruikt in alle methodes van die klasse. Refereren ernaar gebeurt op basis van de naam. Buiten de class-scope zijn enkel de members die zichtbaar zijn voor de buitenwereld toegankelijk en dit via de naam van het object.naammember. Een variabele binnen een methode is enkel toegankelijk in die methode en heeft block scope. Een variabele met block scope kan dezelfde naam hebben als variabele met class-scope. In dat geval hides de methode variabele de class scope variabele. Om toch toegang te hebben tot class scope variabele gebruik je dan keyword Me en de dot operator Visual Basic.NET
5.4 Toegang tot members Access Modifiers Controleren van de toegang tot de instance variabelen en methodes van een klasse Public Toegankelijk van buitenaf. Vormen de interface van de klasse Private Leden zijn niet van buitenaf toegankelijk, enkel binnen de klasse Indien je ze van buitenaf probeert te benaderen, genereert de compiler een foutmelding Friend Enkel toegankelijk binnen het project Protected Enkel toegankelijk voor klassen die erven van deze klasse De access modifiers Public, Private,... bepalen de toegang tot de instance variabelen en de methodes. VB biedt data hiding. Het verbergen van data, dwz de gegevens die opgeslagen zijn in variabelen van een object. Als je private members toch probeert te accessen van buitenaf dan krijg je de melding : is not accessible in this context because it is private. Set- en get-methodes kunnen de data omzetten van het formaat van de interface naar dat van de implementatie en omgekeerd Visual Basic.NET
5.4 Toegang tot members Toegang tot private data : Properties Stelregel : maak data in klasse private! Ontwikkel een interface om deze data te manipuleren! Bevat 2 accessors Get : opvragen van private data Converteren van data naar een extern formaat Set : instellen van private data Validatie van de data Converteren van data naar een intern formaat Toegang tot private data moet gecontroleerd gebeuren gebruik makend van methodes van de class. Om een gebruiker toe te laten om waarden van een private data te lezen, moet de class voorzien in een property definition. Properties zijn een speciaal type methode. Het is een methode specifiek ontworpen voor het instellen van de data waarden en het lezen van de data waarden. Een property definitie bevat accessors : get set Set- en get-methodes kunnen de data omzetten van het formaat van de interface naar dat van de implementatie en omgekeerd Visual Basic.NET
5.5 Constructor Voorbeeld Wordt automatisch uitgevoerd bij creatie van een nieuw object van die klasse adhv de New operator Dim ObjectReference As New ClassName(arguments) Verzorgt de initialisatie van het object Heeft de naam New Kan initializers (parameters) bevatten Heeft geen return type Er kunnen meerdere constructors bestaan binnen 1 klasse (overloading) Voorbeeld Public Sub New() SetTime(0, 0, 0) End Sub In .NET kunnen klassen een speciale methode implementeren die altijd wordt uitgevoerd bij creatie van een object? Deze methode wordt de constructor genoemd, en krijgt altijd de naam NEW. De constructor is de plaats voor initialisatie code, daar het altijd wordt uitgevoerd voordat om het even welke methode kan worden aangeroepen. En het wordt ook maar 1 keer per object uitgevoerd. We kunnen natuurlijk meerdere objecten van de klasse maken, maar de constructor wordt maar 1 keer per gecreeerd object uitgevoerd. Bij de creatie van het object : Dim ObjectReference As New ClassName(arguments) objectreference = naam van de variabel die een verwijzing zal bevatten naar een object van het type ClassName New = betekent dat een nieuw object aangemaakt wordt ClassName : duidt op het type van het object Arguments : specifieren de values gebruikt door de constructor om een object te initialiseren. Dit worden initializers genoemd. Een constructor met argumenten wordt een parameterised constructor genoemd Visual Basic.NET
5.5 Constructor Klassen zonder constructor Klassen met constructors de compiler maakt zelf een default constructor aan (geen argumenten en geen code) Deze default constructor initialiseert enkel de members met hun default waarden (boolean : false; getallen : 0, objecten : nothing) Klassen met constructors Als een klasse enkel constructors met parameters bevat, en geen default constructor, dan krijgt de klasse geen default constructor. Als bij creatie van een object wordt gepoogd een default constructor aan te roepen => syntax fout Default constructor = de constructor New zonder parameters. De programmeur kan zelf een default constructor aanmaken. Als er geen enkele constructor bestaat voor die klassen dan wordt een default constructor door de compiler aangemaakt. Visual Basic.NET
5.5 Constructor Variabele Initializers Variabelen worden geinitialiseerd door de runtime nog voor de constructor wordt uitgevoerd Voorbeeld Public Class TV Private mChannel as Integer = 0 Private mOn As Boolean = True Private mVolume As Double = .5 End Class Variabelen worden geinitialiseerd door de runtime alvorens de instruction pointer de constructor binnengaat. Als ze geen waarden hebben krijgen ze de default waarde. Visual Basic.NET
5.6 Constructor overloading Een klasse met meer dan 1 constructor Onderscheid tussen de verschillende constructors Aantal argumenten Type van de argumenten Voorbeeld Dim time1 As New CTime() Dim time2 As New CTime(2) Dim time3 As New CTime(21, 34) Dim time4 As New CTime(12, 25, 42) Dim time5 As New CTime(27, 74, 99) Dim time6 As New CTime(time4) ' use time4 as initial value De compiler moet op grond van het type en aantal argumenten eenduidig kunnen beslissen voor 1 van de constructoren; Visual Basic.NET
5.6 Constructor overloading constructor initializes each variable to zero and ensures that each object starts in consistent state Public Sub New() SetTime() End Sub ' New ‘ constructor: hour supplied; minute and second default to 0 Public Sub New(ByVal hourValue As Integer) SetTime(hourValue) ' constructor: hour and minute supplied; second defaulted to 0 Public Sub New(ByVal hourValue As Integer, ByVal minuteValue As Integer) SetTime(hourValue, minuteValue) ‘constructor: hour, minute and second supplied Public Sub New(ByVal hourValue As Integer, ByVal minuteValue As Integer, _ ByVal secondValue As Integer) SetTime(hourValue, minuteValue, secondValue) ' constructor: another CTime object supplied Public Sub New(ByVal timeValue As CTime) SetTime(timeValue.mHour, timeValue.mMinute, timeValue.mSecond) De compiler moet op grond van het type en aantal argumenten eenduidig kunnen beslissen voor 1 van de constructoren; Elke constructor roept de settime methode op, waardoor je oplegt dat alle objecten beginnen in een consistente status, daar alle out-of-range waarden op 0 ingesteld worden.De VB runtime roept de juiste methode aan, door matching van aantal, type en volgorde van argumenten zoals gedefinieerd werd in de constructors. Geen enkele constructor heeft een return type (anders wordt een syntax fout gegenereerd). Iedere constructor heeft een verschillend aantal argumenten of type van argumenten. Alhoewel niet alle constructors 3 waarden als input hebben roepen ze toch allen settime op soms met 0, soms met 1, soms met 2 soms met 3 parameters. Reden optional keyword in settime Visual Basic.NET
5.6 Constructor overloading Public Sub SetTime(Optional ByVal hourValue As Integer = 0, _ Optional ByVal minuteValue As Integer = 0, _ Optional ByVal secondValue As Integer = 0) ' perform validity checks on hour, then set hour If (hourValue >= 0 AndAlso hourValue < 24) Then mHour = hourValue Else mHour = 0 End If ' perform validity checks on minute, then set minute If (minuteValue >= 0 AndAlso minuteValue < 60) Then mMinute = minuteValue mMinute = 0 ' perform validity checks on second, then set second If (secondValue >= 0 AndAlso secondValue < 60) Then mSecond = secondValue mSecond = 0 End Sub De settime dient dan optionele parameters te bevatten. Visual Basic.NET
5.6 Constructor overloading Werken met optionele parameters Public Sub New(Optional ByVal hourValue As Integer = 0, _ Optional ByVal minuteValue As Integer = 0, _ Optional ByVal secondValue As Integer = 0) SetTime(hourValue, minuteValue, secondValue) End Sub ' New Public Sub New(ByVal timeValue As CTime) SetTime(timeValue.mHour, timeValue.mMinute, timeValue.mSecond) Je kan ook werken met optionele parameters. Wat het aantal overloads drastisch doet dalen Visual Basic.NET
5.6 Constructor overloading Oproepen van Me.new Public Class Window Private Topleft As Point Private Size As Size Private Caption As String Public Sub New(ByVal topleft As Point, ByVal size As size, ByVal caption As String) Me.topleft = topleft Me.size = size Me.caption = caption End Sub Public Sub New(ByVal x As Integer, ByVal y As Integer, _ ByVal width As Integer, ByVal height As Integer, ByVal caption As String) Me.New(New Point(x, y), New Size(width, height), caption) End Class Vaak zal een constructor de code oproepen van een andere constructor. Dit doe je adhv Me.New(...). Dit betekent dat de constructor dan niet zelf het object creeert maar de creatie delegeert naar een andere constructor, nl diegene die wordt opgeroepen door Me.New. Dit statement moet altijd als eerste statement in een constructor staan, anders compiler error “a direct call to a constructor is allowed only as the first statement in an instance constructor”. Bvb public Sub New(...) Console.writeline (“test”) Me.New(...) End Sub genereert compiler fout. Visual Basic.NET
5.7 Properties Private instance variabelen en Public properties Get accessor : geeft read-access Functie voor uitlezen van een instance variabele Controleert formattering en weergave van de data Set accessor : geeft write-access Functie voor het plaatsen van een waarde in een variabele Validatie Get en Set accessors zijn niet verplicht Een property met enkel een Get accessor is een ReadOnly property Een property met enkel een Set accessor is een WriteOnly property Toegang tot private data moet gecontroleerd gebeuren gebruik makend van methodes van de class. Om een gebruiker toe te laten om waarden van een private data te lezen, moet de class voorzien in een property definition. Properties zijn een speciaal type methode. Het is een methode specifiek ontworpen voor het instellen van de data waarden en het lezen van de data waarden. Een property definitie bevat accessors : get set Set- en get-methodes kunnen de data omzetten van het formaat van de interface naar dat van de implementatie en omgekeerd Een property is een attribuut van een object, en wordt gedefinieerd door zijn get en set accessors. Daar waar een member variabele rechtstreeks gelinkt wordt met zijn geheugenallocatie, is dit niet het geval voor een property : een property heeft enkel accessors wat essentiele functies zijnwaarin instructies gedefinieerd worden om de property waarden te lezen en te schrijven. Vb van read only property : Bij class persoon heb je bvb read-write property voor geboortedatum, maar enkel een readonly property voor leeftijd. Voorbeeld Public ReadOnly Property Age() As Integer Get Return DateDiff(DateInterval.Year, mBirthDate, Now()) End Get End Property Visual Basic.NET
5.7 Properties Toevoegen van een property aan een klasse Declaratie van lokale variabele voor bijhouden van waarde (indien nodig) Private mHour As Integer Declareer property Typ in de keywords Public Property gevolgd door naam van property en data type property .Net genereert automatisch raamwerk met Get en Set Public Property Hour() As Integer Get End Get Set(ByVal Value As Integer) End Set End Property Schrijf de code voor Get en Set property procedures. Visual Basic.NET
5.7 Properties Voorbeeld property Hour Definitie property Hour 56 Public Property Hour() As Integer 57 58 ' return mHour value 59 Get 60 Return mHour 61 End Get 62 63 ' set mHour value 64 Set(ByVal value As Integer) 65 66 If (value >= 0 AndAlso value < 24) Then 67 mHour = value 68 Else 69 mHour = 0 70 End If 71 72 End Set 73 74 End Property ' Hour Definitie property Hour Validatie input mHour In de standaarden zeggen ze van ipv mHour de naam hourValue te gebruiken voor de bijhorende private variabele. Gebruik van get en set is mooier dan bvb het gebruiken van publieke methodes Public Sub SetHour(Byval Hour as Integer) mHour = Hour End Sub Public Function GetHour() as integer return mHour End function Oproepen van de methodes zou zijn Dim mytime as new ctime mytime.setHour(10) Messagebox.shox(mytime.getHour()) Het is toch mooier als je in je code kan schrijven mytime. Hour = 10 Messagebox.shox(mytime.Hour) Visual Basic.NET
5.7 Properties De settime procedure wordt dan ' set new time value using universal time; uses properties to perform validity checks on data Public Sub SetTime(ByVal hourValue As Integer, _ ByVal minuteValue As Integer, ByVal secondValue As Integer) Hour = hourValue ' looks Minute = minuteValue ' dangerous Second = secondValue ' but it is correct End Sub ' SetTime In de standaarden zeggen ze van ipv mHour de naam hourValue te gebruiken voor de bijhorende private variabele. Visual Basic.NET
5.8 Objecten als instances van andere klassen Compositie: gebruik van referenties naar objecten van bestaande klasses als members van nieuwe objecten “heeft een”-relatie Vb1. Een alarmklok heeft een tijd Dus de klasse CAlarmClock zal als instantievariabele een referentie naar een CTime object hebben Vb2. Een werknemer heeft een geboortedatum en een inhuurdatum Misschien aanpassen zodat je verder met de klasse CTIMe blijft werken maar nu een klasse LES maakt. Een les heeft een beginuur en een einduur. Visual Basic.NET
Declaratie van 3 Integers als Private instantievariabelen 1 'CDay.vb 2 ' Encapsulates month, day and year. 3 4 Imports System.Windows.Forms 5 6 Class CDay 7 Inherits Object 8 9 Private mMonth As Integer ' 1-12 10 Private mDay As Integer ' 1-31 based on month 11 Private mYear As Integer ' any year 12 13 ' constructor confirms proper value for month, then calls 14 ' method CheckDay to confirm proper value for day 15 Public Sub New(ByVal monthValue As Integer, _ 16 ByVal dayValue As Integer, ByVal yearValue As Integer) 17 18 ' ensure month value is valid 19 If (monthValue > 0 AndAlso monthValue <= 12) Then 20 mMonth = monthValue 21 Else 22 mMonth = 1 23 24 ' inform user of error 25 Dim errorMessage As String = _ 26 "Month invalid. Set to month 1." 27 28 MessageBox.Show(errorMessage, "", _ 29 MessageBoxButtons.OK, MessageBoxIcon.Error) 30 End If 31 32 mYear = yearValue 33 mDay = CheckDay(dayValue) ' validate day 34 35 End Sub ' New Declaratie van 3 Integers als Private instantievariabelen Constructor voor CDay klasse met 3 argumenten Visual Basic.NET
37 ' confirm proper day value based on month and year 38 Private Function CheckDay(ByVal testDayValue As Integer) _ 39 As Integer 40 41 Dim daysPerMonth() As Integer = _ 42 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 43 44 If (testDayValue > 0 AndAlso _ 45 testDayValue <= daysPerMonth(mMonth)) Then 46 47 Return testDayValue 48 End If 49 50 ' check for leap year in February 51 If (mMonth = 2 AndAlso testDayValue = 29 AndAlso _ 52 mYear Mod 400 = 0 OrElse mYear Mod 4 = 0 AndAlso _ 53 mYear Mod 100 <> 0) Then 54 55 Return testDayValue 56 Else 57 58 ' inform user of error 59 Dim errorMessage As String = _ 60 "day " & testDayValue & "invalid. Set to day 1. " 61 62 MessageBox.Show(errorMessage, "", _ 63 MessageBoxButtons.OK, MessageBoxIcon.Error) 64 65 Return 1 ' leave object in consistent state 66 End If 68 End Function ' CheckDay 69 70 ' create string containing month/day/year format 71 Public Function ToStandardString() As String 72 Return mMonth & "/" & mDay & "/" & mYear 73 End Function ' ToStandardString 75 End Class ' CDay Visual Basic.NET
1 ' CEmployee.vb 2 ' Represent employee name, birthday and hire date. 4 Class CEmployee 5 Inherits Object 6 7 Private mFirstName As String 8 Private mLastName As String 9 Private mBirthDate As CDay ' member object reference 10 Private mHireDate As CDay ' member object reference 11 12 ' CEmployee constructor 13 Public Sub New(ByVal firstNameValue As String, _ 14 ByVal lastNameValue As String, _ 15 ByVal birthMonthValue As Integer, _ 16 ByVal birthDayValue As Integer, _ 17 ByVal birthYearValue As Integer, _ 18 ByVal hireMonthValue As Integer, _ 19 ByVal hireDayValue As Integer, _ 20 ByVal hireYearValue As Integer) 21 22 mFirstName = firstNameValue 23 mLastName = lastNameValue 24 25 ' create CDay instance for employee birthday 26 mBirthDate = New CDay(birthMonthValue, birthDayValue, _ 27 birthYearValue) 29 ' create CDay instance for employee hire date 30 mHireDate = New CDay(hireMonthValue, hireDayValue, _ 31 hireYearValue) 32 End Sub ' New 34 ' return employee information as standard-format String 35 Public Function ToStandardString() As String 36 Return mLastName & ", " & mFirstName & " Hired: " _ 37 & mHireDate.ToStandardString() & " Birthday: " & _ 38 mBirthDate.ToStandardString() 39 End Function ' ToStandardString 41 End Class ' CEmployee 2 Private Strings en 2 Private referenties naar objecten van de klasse CDay als instantievariabelen De constructor van de CDay klasse wordt gebruikt om een geboortedatum en een inhuurdatum aan te maken Visual Basic.NET
5.8 Objecten als instances van andere klassen 1 ' Fig. 8.10: CompositionTest.vb 2 ' Demonstrate an object with member object reference. 3 4 Imports System.Windows.Forms 5 6 Module modCompositionTest 7 8 Sub Main() 9 Dim employee As New CEmployee( _ 10 "Bob", "Jones", 7, 24, 1949, 3, 12, 1988) 11 12 MessageBox.Show(employee.ToStandardString(), _ 13 "Testing Class Employee") 14 End Sub ' Main 15 16 End Module ' modCompositionTest Om een werknemer aan te maken wordt de constructor van de CEmployee klasse opgeroepen, die op zijn beurt tweemaal de constructor van de CDay klasse zal oproepen voor de constructie van de geboorte- en inhuurdatum Visual Basic.NET
Oefening Pas de CDay klasse aan met een methode NextDay die de datum met één dag verhoogt. Het CDay object moet steeds in een consistente staat blijven. Schrijf een programma dat de NextDay methode test in een lus waarbij in elke iteratie de huidige datum getoond wordt om aan te tonen dat de NextDay methode op een correcte manier werkt. Let hierbij vooral op: Overgang naar een nieuwe maand Overgang naar een nieuw jaar Visual Basic.NET
5.9 Gebruik van de Me referentie Elk object heeft toegang tot een referentie naar zichzelf via Me Expliciet: voor de duidelijkheid, zelfs al is het niet nodig Impliciet: om te refereren naar instantievariabelen, eigenschappen en methodes van een object The explicit use of the Me reference can increase program clarity where Me is optional Visual Basic.NET
5.9 Gebruik van de Me referentie 1 ' CTime4.vb 2 ' Encapsulate time using Me reference. 3 4 Class CTime4 5 Private mHour, mMinute, mSecond As Integer 6 7 ' CTime4 constructor 8 Public Sub New(ByVal mHour As Integer, _ 9 ByVal mMinute As Integer, ByVal mSecond As Integer) 10 11 Me.mHour = mHour 12 Me.mMinute = mMinute 13 Me.mSecond = mSecond 14 End Sub ' New 15 16 ' create String using Me and implicit references 17 Public Function BuildString() As String 18 Return "Me.ToUniversalString(): " & Me.ToUniversalString() _ 19 & vbCrLf & "ToUniversalString(): " & ToUniversalString() 20 End Function ' BuildString 21 22 ' convert to String in standard-time format 23 Public Function ToUniversalString() As String 24 Return String.Format("{0:D2}:{1:D2}:{2:D2}", _ 25 mHour, mMinute, mSecond) 26 End Function ' ToUniversalString 27 28 End Class ' CTime4 Aangezien de argumenten dezelfde naam hebben als de instantievariabelen, moet je Me gebruiken om expliciet naar de instantievariabelen te refereren Om de functie ToUniversalString op te roepen, is het niet nodig om expliciet Me te gebruiken (lijn 18). Als je het impliciet doet (lijn 19), dan is het resultaat hetzelfde. Visual Basic.NET
5.10 Garbage collection Via keyword new wordt geheugen gealloceerd en daarna wordt de constructor opgeroepen, die mogelijk nog andere systeembronnen nodig heeft (vb. netwerk- en/of databankconnecties). Er moet voor het object een manier zijn om deze terug te geven wanneer het object niet meer gebruikt wordt garbage collection Hoe referentie naar object vernietigen? Expliciet : myPerson=nothing Door onze variabele naar een ander object te doen verwijzen: myPerson = New Person() Impliciet : variabele gaat out-of-scope In .Net wordt een object vernietigd en het geheugen en resources die het gebruikt vrijgegeven als er geen verwijzingen meer zijn naar object. Als we een object gebruiken, bevatten onze variabelen eigenlijk een verwijzing naar het object Dim myPerson As New Person() myPerson is een variabele die wijst naar een Person object. Als we code hebben zoals Dim anotherPerson as Person anotherPerson = myPerson Dan zullen myPerson en AnotherPerson wijzen naar hetzelfde object. Dit betekent dat naar het specifiek Person object verwezen wordt door 2 variabelen. Als er geen variabelen meer wijzen naar een object, wordt het beëindigd door de .NET runtime omgeving. Meer bepaald het wordt terminated en reclaimed door een mechanisme garbage collector genoemd. Hoe kunnen we nu references naar een object elimineren expliciet : myPerson=nothing Door onze variabele naar een ander object te doen verwijzen : myPerson = New Person() Impliciet Wanneer een variabele out of scope gaat. Bvb een variabele binnen een methode , wordt automatisch vernietigd bij het beeindigen van de methode, dus dereferencing elk object waarnaar het verwees. Vb private sub DoSomething() dim myPerson as Person myPerson = New Person() end sub Als de procedure wordt uitgevoerd wordt de variabele myPerson vernietigd na de uitvoering van de methode, daar het out of scope gaat. Een andere mogelijkheid is wanneer de applicatie wordt afgesloten. In dat geval worden alle variabelen vernietigd en verdwijnen dussen alle verwijzingen naar e objecten. In .NET worden objecten vernietigd door de garbage collector. Op bepaalde tijdstippen (gebaseerd op bepaalde regels) zal een taak alle objecten overlopen en nagaan of er nog uitstaande references bestaan voor die objecten. Indien er geen verwijzingen meer zijn, wordt object beëindigd ; the garbage is collected (de afval werd opgehaald).Dit houdt in dat we niet exact weten wanneer een object dan uiteindelijk vernietigd zal worden. Het is niet omdat we alle verwijzingen naar het object elimineren, dat het object zelf onmiddellijk vernietigd wordt. Het blijft in het geheugen bestaan totdat de garbage collector het vernietigd heeft. (=nondeterministic finalization). Je kan de garbage collector triggeren : System.GC.Collect(). Visual Basic.NET
5.10 Garbage collection In VB.Net: Objecten waar geen referenties meer naar bestaan, worden door de garbage collector gezocht, zodat het geheugen automatisch opnieuw kan vrijgeven worden Geen lekken zoals in C of C++ Finalizer methode: zorgt voor de eindhuishouding net voor de garbage collector langskomt In .NET worden objecten vernietigd door de garbage collector. Op bepaalde tijdstippen (gebaseerd op bepaalde regels) zal een taak alle objecten overlopen en nagaan of er nog uitstaande references bestaan voor die objecten. Indien er geen verwijzingen meer zijn, wordt object beëindigd ; the garbage is collected (de afval werd opgehaald).Dit houdt in dat we niet exact weten wanneer een object dan uiteindelijk vernietigd zal worden. Het is niet omdat we alle verwijzingen naar het object elimineren, dat het object zelf onmiddellijk vernietigd wordt. Het blijft in het geheugen bestaan totdat de garbage collector het vernietigd heeft. (=nondeterministic finalization). Zie later bij overerving voor detail; Je kan de garbage collector triggeren : System.GC.Collect(). Garbage collector Resource leaks Objects must have an efficient way to return memory and release resources when the program no longer uses those objects Memory leaks In Visual Basic memory is reclaimed automatically, hence it experiences rare memory leaks as compared to C and C++ Finalization Finalizer method performs termination housekeeping on that object just before the garbage collector reclaims the object's memory Visual Basic.NET
5.11 Shared klasse members Een Shared klassevariabele: Een programma bevat slechts 1 kopie van die variabele in geheugen (Wordt dus maar één keer bijgehouden per klasse, niet één keer per object zoals andere instantievariabelen) Alle klasse objecten delen dezelfde copy van die variabele Is niet hetzelfde als een “global” variabele in C en C++ want Shared klassevariabelen hebben klasse scope. Referentie naar Public Shared member kan via: klasseNaam.sharedMemberNaam Referentie naar Private Shared member kan alleen via members van deze klasse Shared members bestaan gedurende de hele duur van de uitvoering van het programma, zelfs als er geen objecten van die klasse meer bestaan. Alle variabelen en methodes die we tot nu toe gecreeerd hebben zijn instance methods, dit zijn methods die vereisen dat er een instantie van de klasse bestaat alvorens ze kunnen worden aangeroepen; De methodes hebben instance variabelen en member variabelen gebruikt om hun werk te doen – wat betekent dat ze met een set van data gewerkt hebben die uniek is voor elk object. VB.NET laat toe variabelen en methodes te creeeren die behoren tot de klasse eerder dan tot een specifiek object. Dus die behoren tot alle objecten van die klasse en gedeeld worden door alle instanties van die klasse. Visual Basic.NET
5.11 Shared klasse members Een Shared method: Klasse CEmployee2 Heeft geen toegang tot niet-Shared klasse members Heeft geen Me referentie, aangezien ze onafhankelijk is van de klasse objecten en zelfs wanneer er geen objecten van deze klassen zijn toch bestaat Klasse CEmployee2 Gebruikt een Private Shared klassevariabele mCount om het aantal werknemers (= het aantal objecten van de klasse CEmployee2 die in het geheugen zitten, inclusief degene die al gemarkeerd staan om door de garbage collector opgehaald te worden) bij te houden. Shared procedures zijn procedures die niet gekoppeld zijn met een instantie van een klasse. Visual Basic.NET
5.11 Shared klasse members 1 ' CEmployee2.vb 2 ' Class CEmployee2 uses Shared variable. 3 4 Class CEmployee2 5 Inherits Object 6 7 Private mFirstName As String 8 Private mLastName As String 9 10 ' number of objects in memory 11 Private Shared mCount As Integer 12 13 ' CEmployee2 constructor 14 Public Sub New(ByVal firstNameValue As String, _ 15 ByVal lastNameValue As String) 16 17 mFirstName = firstNameValue 18 mLastName = lastNameValue 19 20 mCount += 1 ' increment shared count of employees 21 Console.WriteLine _ 22 ("Employee object constructor: " & mFirstName & _ 23 " " & mLastName) 24 End Sub ' New 25 26 ' finalizer method decrements Shared count of employees 27 Protected Overrides Sub Finalize() 28 mCount -= 1 ' decrement mCount, resulting in one fewer object 29 Console.WriteLine _ 30 ("Employee object finalizer: " & mFirstName & _ 31 " " & mLastName & "; count = " & mCount) 32 End Sub ' Finalize 33 Visual Basic.NET
5.11 Shared klasse members 34 ' return first name 35 Public ReadOnly Property FirstName() As String 36 37 Get 38 Return mFirstName 39 End Get 40 41 End Property ' FirstName 42 43 ' return last name 44 Public ReadOnly Property LastName() As String 45 46 Get 47 Return mLastName 48 End Get 49 50 End Property ' LastName 51 52 ' property Count 53 Public ReadOnly Shared Property Count() As Integer 54 55 Get 56 Return mCount 57 End Get 58 59 End Property ' Count 60 61 End Class ' CEmployee2 Property Count: Is Shared, dus we hebben geen instantie van CEmployee2 nodig om de Get methode op te roepen Is ReadOnly, dus de waarde van mCount zal niet zomaar kunnen veranderd worden door een client van deze interface Als er geen objecten van de klasse CEmployee2 zijn, kan de Property Count gebruikt worden om een referentie naar mCount te verkrijgen. Visual Basic.NET
Twee objecten van de klasse CEmployee2, dus mCount staat op 2. 1 ' SharedTest.vb 2 ' Demonstrates Shared members. 4 Imports System.Windows.Forms 5 6 Module modSharedTest 7 8 Sub Main() 9 Dim output As String 10 11 Console.WriteLine("Employees before instantiation: " & _ 12 CEmployee2.Count) 13 14 Dim employee1 As CEmployee2 = _ 15 New CEmployee2("Susan", "Baker") 17 Dim employee2 As CEmployee2 = _ 18 New CEmployee2("Bob", "Jones") 19 20 ' output of employee2 after instantiation 21 Console.WriteLine(vbCrLf & _ 22 "Employees after instantiation: " & vbCrLf & _ 23 "via Employee.Count: " & CEmployee2.Count) 24 25 ' display name of first and second employee 26 Console.WriteLine(vbCrLf & "Employees 1: " & _ 27 employee1.FirstName & " " & employee1.LastName & _ 28 vbCrLf & "Employee 2: " & employee2.FirstName & " " & _ 29 employee2.LastName) 30 31 ' mark employee1 and employee2 for garbage collection 32 employee1 = Nothing 33 employee2 = Nothing 34 35 System.GC.Collect() ' request garbage collection 36 End Sub ' Main 37 38 End Module ' modShared Twee objecten van de klasse CEmployee2, dus mCount staat op 2. Visual Basic.NET
5.11 Shared klasse members Employees before instantiation: 0 Employee object constructor: Susan Baker Employee object constructor: Bob Jones Employees after instantiation: via Employee.Count: 2 Employees 1: Susan Baker Employee 2: Bob Jones Employee object finalizer: Bob Jones; count = 1 Employee object finalizer: Susan Baker; count = 0 Normaliter wordt de garbage collector niet direct door de gebruiker opgeroepen. Klasse GC uit de namespace System heeft echter wel een Public Shared methode Collect die kan vragen of de garbage collector eens kan langskomen. Vlak voor de garbage collector het geheugen vrijmaakt dat de twee CEmployee objecten innamen, wordt de methode Finalize opgeroepen voor elk object, zodat mCount terug op 0 komt. De volgorde waarin de objecten “gefinaliseerd” worden, kan echter van systeem tot systeem verschillen. Visual Basic.NET
5.12 Const en ReadOnly members Constanten: Const of Readonly gebruiken? Const: MOET geïnitialiseerd worden in de declaratie ReadOnly: KAN geïnitialiseerd worden in de declaratie of in de constructor van de klasse Beiden mogen, eens ze een waarde gekregen hebben, nooit meer aangepast worden Als de waarde van een Const kan bepaald worden door de compiler, dan kan deze toegekend worden aan de Const data member, terwijl de waarde van ReadOnly members slechts at runtime bepaald wordt Vb. Convert.ToDouble (“3.14159”) Er wordt een constante String gebruikt, maar dit geeft een syntax error als je deze waarde aan een Const wilt toekennen, omdat de compiler de waarde nog niet kent. Toekenning aan een ReadOnly kan wel. Constanten : variabelen waarvan de waarde niet kan veranderen tijdens verloop van programma. Gebruik hiervoor const of readonly keyword. Constanten moeten een waarde hebben at compile time. Daarom kunnen ze ook enkel geinitialiseerd worden met constante waarden zoals een integr, literal,... Indien de waarde van de constante niet bepaald kan worden at compile time moet je ReadOnly gebruiken. Vb Const pi as double =convert.todoble(“...”) genereert een compile fout want compiler kan waarde niet berekenen. Opl is readonly Shared readonly members kunnen enkel met een shared constructor geinitialiseerd worden. Visual Basic.NET
5.12 Const en ReadOnly members 1 ' CCircleConstants.vb 2 ' Encapsulate constants PI and radius. 3 4 Class CCircleConstants 5 6 ' PI is constant data member 7 Public Const PI As Double = 3.14159 8 9 ' radius is uninitialized constant 10 Public ReadOnly RADIUS As Integer 11 12 ' constructor of class CCircleConstants 13 Public Sub New(ByVal radiusValue As Integer) 14 RADIUS = radiusValue 15 End Sub ' New 16 17 End Class ' CCircleConstants PI is Const want de waarde 3.14159 is bekend at compile time RADIUS is ReadOnly want de waarde wordt maar bepaald at runtime Lijn 7 : PI krijgt constante waarde (je zou ook Math.PI gebruiken, voorgedefinieerd) Lijn 10 : readonly die waarde krijgt op lijn 14 in de constructor. Visual Basic.NET
5.12 Const en ReadOnly members 1 ' ConstAndReadOnly.vb 2 ' Demonstrates Const and ReadOnly members. 3 4 Imports System.Windows.Forms 5 6 Module modConstAndReadOnly 7 8 Sub Main() 9 Dim random As Random = New Random() 10 Dim circle As CCircleConstants = _ 11 New CCircleConstants(random.Next(1, 20)) 12 13 Dim radius As String = Convert.ToString(circle.RADIUS) 14 15 Dim output As String = "Radius = " & radius & vbCrLf _ 16 & "Circumference = " + String.Format("{0:N3}", _ 17 circle.RADIUS * 2 * CCircleConstants.PI) 18 19 MessageBox.Show(output, "Circumference", _ 20 MessageBoxButtons.OK, MessageBoxIcon.Information) 21 End Sub ' Main 22 23 End Module ' modConstAndReadOnly Random geheel getal bepalen in het interval [1-20] Toegang tot de ReadOnly variabele RADIUS Toegang tot de Const variabele PI Module : Lijn 9-11 genereert een random getal tussen 1 en 20 die overeenkomt met de straal van een cirkel Beide radius en PI werden publiek gedefinieerd in klasse. Dus kunnen we achteraf opvragen Readonly via objnaam.radius Const via de klassenaam.PI (via shared class reference) Visual Basic.NET
5.13 Data abstraction en information hiding Stacks Last In, First Out Vb. Stapel met dienbladen in de cafetaria “push” en “pop” functies Queue First In, First Out Vb. Printer die documenten in FIFO volgorde print “enqueue” en “dequeue” functies Data abstractie: client weet enkel welke functionaliteiten deze structuur biedt, NIET hoe dit precies geïmplementeerd wordt Visual Basic.NET
5.14 Software herbruikbaarheid Rapid Application Development (RAD) Hergebruik van software Snellere ontwikkeling van krachtige software van hoge kwaliteit Visual Basic.NET
5.15 Namespaces en Assemblies Framework Class Library (FCL) .NET framework Moet geïmporteerd worden in een Visual Basic programma door een referentie naar deze bibliotheken toe te voegen (zie Hfdst 2) Namespaces Conventie: unieke klassenamen, zodat er een minimaal aantal collisies kunnen optreden Klasses met dezelfde naam kunnen wél nog in verschillende namespaces voorkomen Bibliotheken moeten geimporteerd worden in programma. Elke klasse in bibliotheek heeft een unieke namespace om name collision te vermijden : 2 klassen met dezelfde naam. Namespaces zorgen voor unieke klasnamen. Visual Basic.NET
5.15 Namespaces en Assemblies Maken van een klassenbibliotheek File > New > Project... Visual Basic Projects als Project Type Class Library als Template Naam: EmployeeLibrary Opm : klasses zijn Public zodat ze toegankelijk zijn van buitenaf Hernoem de klasse Class1.vb in de Solution Explorer als CEmployee.vb en pas de code aan Kies Build > Build Solution om de code te compileren Maakt een dll bestand aan in de bin directory van het project Gebruik in ander project : voeg referentie toe Project > Add Reference Localiseer met Browse de dll Importeer de namespace : Imports EmployeeLibrary Een assembly is de som van de onderdelen die nodig zijn om een applicatie uit te voeren en is zelfbeschrijvens. M.a.w. Een assembly heeft geen externe informatie nodig, zoals entries in de registry om te worden uitgevoerd. Dit is mogelijk dankzij de meta gegevens die zijn ingesloten in het manifest van de assembly. Het manifest bevat alle relevante informatie over de naam, instellingen voor machtigingen en de versie. Het installeren van een assembly kan eenvoudig een kwestie zijn van kopieren van de bestanden en de subdirectories. Assemblies spelen ook een belangrijke rol in het definieren van de versioning van het project. De gebruikte technologie voor het maken van assemblies maakt het mogelijk meerdere versies van een assembly uit te voeren op een computer. Zo kunnen programma’s die afhankelijk zijn van een assembly van een oudere versie ervan blijven gebruiken om problemen in de uitvoering te vermijden, zelfs wanneer een nieuwere versie aanwezig is. Visual Basic.NET
2 ' Class CEmployee3 uses Shared variable. 3 4 Public Class CEmployee3 1 ' CEmployee3.vb 2 ' Class CEmployee3 uses Shared variable. 3 4 Public Class CEmployee3 5 Inherits Object 6 7 Private mFirstName As String 8 Private mLastName As String 9 10 ' number of objects in memory 11 Private Shared mCount As Integer 12 13 ' CEmployee3 constructor 14 Public Sub New(ByVal firstNameValue As String, _ 15 ByVal lastNameValue As String) 16 17 mFirstName = firstNameValue 18 mLastName = lastNameValue 19 20 mCount += 1 ' increment shared count of employees 21 Console.WriteLine _ 22 ("Employee object constructor: " & mFirstName & _ 23 " " & mLastName) 24 End Sub ' New 25 26 ' finalizer method decrements Shared count of employees 27 Protected Overrides Sub Finalize() 28 mCount -= 1 ' decrement mCount, resulting in one fewer object 29 Console.WriteLine _ 30 ("Employee object finalizer: " & mFirstName & _ 31 " " & mLastName & "; count = " & mCount) 32 End Sub ' Finalize 33 Een herbruikbare klassenbibliotheek maken: klasse moet Public zijn zodat andere projecten ze kunnen gebruiken maak van CEmployee3 een dynamic link library EmployeeLibrary.dll die we in andere systemen kunnen hergebruiken 1. Maak een klassenbibliotheek project File > New > Project... Visual Basic Projects als Project Type Class Library als Template Naam: EmployeeLibrary Let op: * geen Main in de code klassenbibliotheek is geen uitvoerbaar bestand * klasses zijn Public zodat ze toegankelijk zijn van buitenaf 2. Hernoem de klasse Class1.vb in de Solution Explorer als CEmployee.vb en pas de code aan 3. Kies Build > Build Solution om de code te compileren Als het gelukt is, bevindt de file EmployeeLibrary.dll zich in de bin directory van het project Visual Basic.NET
5.15 Namespaces en Assemblies 34 ' return first name 35 Public ReadOnly Property FirstName() As String 36 37 Get 38 Return mFirstName 39 End Get 40 41 End Property ' FirstName 42 43 ' return last name 44 Public ReadOnly Property LastName() As String 45 46 Get 47 Return mLastName 48 End Get 49 50 End Property ' LastName 51 52 ' property Count 53 Public ReadOnly Shared Property Count() As Integer 54 55 Get 56 Return mCount 57 End Get 58 59 End Property ' Count 60 61 End Class ' CEmployee3 Module demonstreert het gebruik van de klasselibrary. Visual Basic.NET
Referentie naar de EmployeeLibrary.dll file 1 ' AssemblyTest.vb 2 ' Demonstrates assembly files and namespaces. 3 4 Imports EmployeeLibrary ' contains class CEmployee3 5 6 Module modAssemblyTest 7 8 Public Sub Main() 9 Dim output As String 10 11 Console.WriteLine("Employees before instantiation: " & _ 12 CEmployee3.Count) 13 14 Dim employee1 As CEmployee3 = _ 15 New CEmployee3("Susan", "Baker") 16 17 Dim employee2 As CEmployee3 = _ 18 New CEmployee3("Bob", "Jones") 19 20 ' output of employee after instantiation 21 Console.WriteLine(vbCrLf & "Employees after instantiation:" _ 22 & vbCrLf & "via Employee.Count: " & CEmployee3.Count) 23 24 ' display name of first and second employee 25 Console.WriteLine(vbCrLf & "Employees 1: " & _ 26 employee1.FirstName & " " & employee1.LastName & _ 27 vbCrLf & "Employee 2: " & employee2.FirstName & " " & _ 28 employee2.LastName) 29 30 ' mark employee1 and employee2 for garbage collection 31 employee1 = Nothing 32 employee2 = Nothing 33 34 System.GC.Collect() ' request garbage collection 35 End Sub ' Main 36 37 End Module ' modAssemblyTest Referentie naar de EmployeeLibrary.dll file Om een referentie naar de assembly te creëren, kies Project > Add Reference Gebruik de Browse knop om EmployeeLibrary.dll (te vinden in de bin directory van het EmployeeLibrary project) te selecteren Klik OK om deze bron toe te voegen aan het project Gebruik Imports gevolgd door de naam van de namespace (EmployeeLibrary) om de compiler te informeren over het gebruik van de klassen uit deze namespace (zie lijn 4) Visual Basic.NET
5.15 Namespaces en Assemblies Employees before instantiation: 0 Employee object constructor: Susan Baker Employee object constructor: Bob Jones Employees after instantiation: via Employee.Count: 2 Employees 1: Susan Baker Employee 2: Bob Jones Employee object finalizer: Bob Jones; count = 1 Employee object finalizer: Susan Baker; count = 0 Visual Basic.NET
5.16 Class View en Object Browser Toont de klassen uit een project Kies View > Class View Hiërarchische structuur van knopen (klasses, variabelen, methodes, …) Object Browser Toont de Framework Class Library (FCL) klasses die beschikbaar zijn in Visual Basic Om deze te openen, klik met de rechtermuisknop op om het even welke klasse of methode in de code editor en kies Go To Definition De Object Browers toont de functionaliteit voorzien voor het specifieke object Visual Basic.NET
5.16 Class View en Object Browser Class View van CTime klasse en modTimeTest module Visual Basic.NET
5.16 Class View en Object Browser Object Browser wanneer de gebruiker rechts klikt op Object uit CTime.vb Visual Basic.NET
Alle icoontjes Visual Basic.NET
Addendum UML Object -> .Net Object Entiteit met toestand, gedrag en identiteit UML Class -> .NET Class of Structure Entiteit met rol van type, factory en service object UML Association -> .NET Reference Entiteit voor communicatie tussen objecten Visual Basic.NET
Addendum UML Package -> .Net Project Verzameling van elementen (classes, interfaces, sub-packages) UML Component -> .NET Assembly Entiteit voor het bouwen van applicaties Visual Basic.NET
5.2 Implementatie van klasse CTime Abstract Data Types (ADT) Klassen laten toe een data type te definieren Instance variable Object in consistente staat Initializeert de instance variables Informatie hiding Programma’s die nooit aangepast moeten worden, vormen een uitzondering. Om te kunnen anticiperen op deze veranderingen, is het goed dat klasses gebruikt worden, zodat het programma gemakkelijker aanpasbaar is. ADT’s vereenvoudigen de creatie van speciale datatypes in .NET, ADT’s genoemd. ADT voorzien in een implementatie onafhankelijke interface met de clients. De ontwikkelaar van de ADT kan de implementatie van zijn klasse wijzigen zonder dat de consumers van die klasse aangepast dienen te worden. . Als het ADT aangepast wordt, hoeven de klasses niet herschreven te worden, aangezien de ADTs implementatie-onafhankelijke interfaces zijn voor hun clients. Visual Basic.NET