VB, Grundkurs i objektorientering OOP
Förord
Hej. Jag heter Peter Holm och besöker ofta denna ypperliga webbplats som Pelle skapat. Tänkte nu berika den ytterligare med en liten kurs i objektorienterad programmering för nybörjare. Optimering har det pratats en hel del om i areorna på Pellesoft, men optimering i all ära. Det jag skall ta upp är en av VB:s egenskaper som ofta glöms bort då det är lätt att springa iväg och koda all kod i ett formulär till exempel.Jag skall hålla en kurs i Objektorienterad programmering för nybörjare som alltid skriver all sin kod i formuläret. Objektorientering är ingenting nytt. Redan på 1960-talet skapades simula av två norrmän, O.J.Dahl och Kristen Nygaard som ville härma den verkliga värden i sina komplexa simuleringar av olika fysiska system.
VB är ju inte i grund och botten riktigt objektorienterat språk. Det som fattas för att det skall få kalla sig detta är Arv. Vi återkommer till detta i slutet av kapitel 1. Ett objektorienterat språk har tre egenskaper som gör att dem är just objektorienterade. de tre är.
Inkapsling, polymorfism och arv.
Jag skall kortfattat beskriva dessa tre egenskaper.
Inkapsling syftar till att kapsla in data i objektet. Se objektet som ett skal som skyddar sitt data. Datat är endast åtkomligt via sitt interface. Interfacet är alla publika metoder och egenskaper som objektet har. Tag objektet bil som har en bensintank. Bensintanken är i normala fall ej direkt åtkomlig för avläsning av bränslenivån. För detta ändamål använder vi interfacet bränslemätare som låter oss avläsa tankens nivå.
Polymorfism. Flera givna objekt kan ha samma metod för att utföra sina uppgifter. Du kan ha en collection av bilar. Du behöver inte bry dig om ifall det är en Saab, Volvo eller Opel. Alla har metoden sväng(vänster) eller bromsa(hårt). Du kan till och med lägga objektet Cykel till din collection och ändå uppfyller du kraven på polymorfism eftersom en cykel också har en metod sväng(vänster).
Arv låter dig från en given superklass ärva egenskaper till subklasser. Du har en superklass Bil som du låter ärva när du skapar klasserna Volvo och Saab. Volvo och Saab är ju båda bilar med samma metoder och egenskaper. Utöver dessa gemensamma metoder och egenskaper som ges av arvet från superklassen kan man lägga unika metoder och egenskaper som endast respektive bilmodell har.
I början skrev jag ju att VB inte är ett rent objektorienterat språk. Vad är då VB? Visual Basic är ett händelsestyrt objektbaserat språk som har vissa av de egenskaper som ett objektorienterat språk har.
För att enklast förstå inkapsling skall jag visa ett exempel på detta. För att du skall hänga med och testa exemplen startar du VB och följer instruktionerna.
Lägg in följande kod i din klassmodul.
I koden ovan har vi skapat två interface-metoder med vilka objektet kan kommunicera med omvärlden. Vi har dessutom en lokal variabel som inte endast är åtkomlig via interfacet. Jämför med exemplet i kapitel 1 och bränsletanken.
Lägg följande kod i Form1. Låt namnet på Form1 kvarstå tills vidare. Lägg dock en Command1 och en Text1 i ditt formulär.
Först anger vi att vi explicit kommer deklarera alla våra variabler i denna form. Option Explicit. Därefter Instansierar vi ett nytt objekt som vi kallar för Batteri. Vi använder vår pepparkaksform och trycker ut en pepparkaka.
Som vi kan se laddas batteriet i formulärets Load-Händelse som triggas varje gång formuläret laddas. Genom att klicka på Command1 fylls Text1 i med batteriets energi-nivå. Här skulle du kanske vilja ha skrivit något i stil med. Text1.text = Batteri.energyLevel Men skulle generera ett körfel. Method or data member not found. Den variabeln är ju gömd inne i objektet och kan endast kommas åt via interface-metoden energy. Detta är inkapsling.
Polymorfism är ett grekiskt ord som betyder ungefär "många former" och det är precis en träffande översättning. Tänk att vi har ett antal olika objekt. Bil, Båt, Traktor och Cykel. Alla dessa objekt har metoden turnLeft(). Men en bil implementerar sitt eget sätt att svänga vänster, ett flygplan likaså för att inte prata om hur en Cykel implementerar sin metod att svänga vänster. För programmerare är detta en mycket kraftfull egenskap som OO-programmering har.
Nu skall jag visa detta med några rader enkel kod. Så skapa ett nytt VB-projekt och klistra in kodsnuttarna här nedan.
Form1
Sätt ut tre textboxar på form1, text1 - text3. Sätt dessutom ut tre commando-knappar, command1 - command3.
Lägg sedan till tre klassmoduler.
Via projekt-menyn kan du lägga till tre klassmoduler. Markera sedan en i taget och byt namn på dem till clsBil, clsTraktor och clsCykel. Egenskaperna för klassmodulen får du fram genom att trycka F4.
clsBil
clsTraktor
clsCykel
Japp det var väl ungefär allt. När du nu kör detta exempel kommer 10 fordon (0-9) att skapas. Klicka på command1 för att slumpa fram ett fordon. Klicka på command2 för att identifiera fordonet och command3 för att få reda på dess hastighet. Oavsett om det är en cykel, bil eller traktor svarar det på samma interfacemetoder. Dock har respektive objekt implementerat sitt sätt att ange hastighet på tillexempel. Detta är "polymorfism".
Lektion 4. Händelser, (events)
Nu är det lagom att ta upp en annan kraftfull egenskap hos VB. Detta har dock inget med objhekt-orientering att göra, men det kan vara på sin plats att ändå ta upp detta nu.
Mycket i VB styrs ju av händelser som triggas när formar laddas, knappar klickas och textboxar ändras. Det finns så många händelser att de verkar förvirrande i början. Bara när du startar ditt program triggas fyra events på raken. Nämligen form_initialize, form_load, form_resize och form_activate. Inte nog att det är ett måste att veta vilka events som triggas när, du måste vet i vilken ordning också annars kan ditt program ofta bete sig rätt synnerligt.
När man håller på med events gäller det dock att se upp så man inte ställer till det för sig. Det finns risk att hamna i rekursiva event loopar. Säg att du har en form med en checkbox. när du ändrar dess värde så triggas eventet check_click(), om du i den subrutinen lägger kod för att ändra status på checkboxen kommer eventet att triggas igen. Du är inne i en rekursiv loop som tillslut kommer ge ett fel då minnet tar slut.
Betrakta följande kod:
VB kan du givetvis skapa egna händelser. Detta är en mycket kraftfull egenskap. Jag skall med ett exempel visa hur du gör en enkel timer istället för att använda den befintliga. Starta ett nytt VB standard projekt. Lägg till en form1, command1, command2. Lägg dessutom till en klassmodul som du byter namn på till clsTimer.
Klistra in koden nedan och kör programmet. Kommentarer finns i koden.
Form1
clsTimer
Jag planerar ytterligare lektioner och skall då höja svårighetsgraden lite och tillämpa de saker vi lärt oss ovan. Jag skall visa hur man på ett objektorienterat sätt kan simulera en klocka. Hur man identifierar de olika ingående objekten och omsätter dessa i kod.
Om du gör någon intressant (eller kanske något konstigt fel) på grund av detta material så skicka gärna det med ett mail eller bifoga en länk till mig så presenterar jag detta som ytterligare exempelfiler för kursen. Om detta innehållet är felaktigt eller du lärt dig fler finesser så skriv gärna en rad eller varför inte en egen kurs baserat på dina erfarenheter. Sänd gärna in dina tips till denna kurs.
/Peter Holm
Lektion 1. Grunder i OO-programmering
VB är ju inte i grund och botten riktigt objektorienterat språk. Det som fattas för att det skall få kalla sig detta är Arv. Vi återkommer till detta i slutet av kapitel 1. Ett objektorienterat språk har tre egenskaper som gör att dem är just objektorienterade. de tre är.Inkapsling, polymorfism och arv.
Jag skall kortfattat beskriva dessa tre egenskaper.
Inkapsling syftar till att kapsla in data i objektet. Se objektet som ett skal som skyddar sitt data. Datat är endast åtkomligt via sitt interface. Interfacet är alla publika metoder och egenskaper som objektet har. Tag objektet bil som har en bensintank. Bensintanken är i normala fall ej direkt åtkomlig för avläsning av bränslenivån. För detta ändamål använder vi interfacet bränslemätare som låter oss avläsa tankens nivå.
Polymorfism. Flera givna objekt kan ha samma metod för att utföra sina uppgifter. Du kan ha en collection av bilar. Du behöver inte bry dig om ifall det är en Saab, Volvo eller Opel. Alla har metoden sväng(vänster) eller bromsa(hårt). Du kan till och med lägga objektet Cykel till din collection och ändå uppfyller du kraven på polymorfism eftersom en cykel också har en metod sväng(vänster).
Arv låter dig från en given superklass ärva egenskaper till subklasser. Du har en superklass Bil som du låter ärva när du skapar klasserna Volvo och Saab. Volvo och Saab är ju båda bilar med samma metoder och egenskaper. Utöver dessa gemensamma metoder och egenskaper som ges av arvet från superklassen kan man lägga unika metoder och egenskaper som endast respektive bilmodell har.
I början skrev jag ju att VB inte är ett rent objektorienterat språk. Vad är då VB? Visual Basic är ett händelsestyrt objektbaserat språk som har vissa av de egenskaper som ett objektorienterat språk har.
Lektion 2. Inkapsling
För att enklast förstå inkapsling skall jag visa ett exempel på detta. För att du skall hänga med och testa exemplen startar du VB och följer instruktionerna.- Skapa ett standard VB-projekt.
- Lägg till en Klass Modul via projektmenyn. Tryck F4 för att få fram klassmodulens egenskaper och ändra sedan namnet till clsBatteri (Jag får anledning att återkomma till hur man namnger sina klasser och objekt.)
Lägg in följande kod i din klassmodul.
Option Explicit
Private energyLevel As Integer 'Lokal kopia för energi-nivå 0-100%
Public Sub charge() 'Interface-metoden för att ladda batteriet
energyLevel = 100
End Sub
Public Function energy() As Integer 'Interface-metoden för att avläsa batteriets laddning
energy = energyLevel
End Function
I koden ovan har vi skapat två interface-metoder med vilka objektet kan kommunicera med omvärlden. Vi har dessutom en lokal variabel som inte endast är åtkomlig via interfacet. Jämför med exemplet i kapitel 1 och bränsletanken.
Lägg följande kod i Form1. Låt namnet på Form1 kvarstå tills vidare. Lägg dock en Command1 och en Text1 i ditt formulär.
Option Explicit
Private Batteri As New clsBatteri 'Instansiera klassen clsBatteri
Private Sub Command1_Click()
Text1.Text = Batteri.energy 'Visa batterinivå i text1
End Sub
Private Sub Form_Load()
Batteri.charge 'Ladda batteriet
End Sub
Först anger vi att vi explicit kommer deklarera alla våra variabler i denna form. Option Explicit. Därefter Instansierar vi ett nytt objekt som vi kallar för Batteri. Vi använder vår pepparkaksform och trycker ut en pepparkaka.
Som vi kan se laddas batteriet i formulärets Load-Händelse som triggas varje gång formuläret laddas. Genom att klicka på Command1 fylls Text1 i med batteriets energi-nivå. Här skulle du kanske vilja ha skrivit något i stil med. Text1.text = Batteri.energyLevel Men skulle generera ett körfel. Method or data member not found. Den variabeln är ju gömd inne i objektet och kan endast kommas åt via interface-metoden energy. Detta är inkapsling.
Lektion 3. Polymorfism
Polymorfism är ett grekiskt ord som betyder ungefär "många former" och det är precis en träffande översättning. Tänk att vi har ett antal olika objekt. Bil, Båt, Traktor och Cykel. Alla dessa objekt har metoden turnLeft(). Men en bil implementerar sitt eget sätt att svänga vänster, ett flygplan likaså för att inte prata om hur en Cykel implementerar sin metod att svänga vänster. För programmerare är detta en mycket kraftfull egenskap som OO-programmering har. Nu skall jag visa detta med några rader enkel kod. Så skapa ett nytt VB-projekt och klistra in kodsnuttarna här nedan.
Form1
Sätt ut tre textboxar på form1, text1 - text3. Sätt dessutom ut tre commando-knappar, command1 - command3.
Option Explicit
'I detta exempel använder jag en array. Man skulle kunne
'Använda en Collection, men vi ökar på svårigheterna längre
'fram i kursen.
Private Fordon(0 To 9) As Object
Private Sub Command1_Click()
Text1.Text = CStr(Int(10 * Rnd)) 'Slumptal mellan 0 och 9
End Sub
Private Sub Command2_Click()
'Fråga fordonet om vad det är för en typ av fordon
Text2.Text = Fordon(Val(Text1.Text)).Identifiera
End Sub
Private Sub Command3_Click()
'Fråga fordonet om dess hastighet
Text3.Text = Fordon(Val(Text1.Text)).Ange_Hastighet
End Sub
Private Sub Form_Load()
'Sätt en referens till de 10 objekten. Slumpvis
'Vi kommer alltså inte veta vilket objekt som
'blir vilken typ av fordon. Det gör inget eftersom
'Vi vet att alla objekt har samma interfacemetoder
'Som vi kan kommunicera med. POLYMORFISM
Dim i As Integer
For i = 0 To 9
Select Case Int(3 * Rnd) + 1
Case 1: Set Fordon(i) = New clsBil
Case 2: Set Fordon(i) = New clsCykel
Case 3: Set Fordon(i) = New clsTraktor
End Select
Next i
'Sätt maxlängden på text1, 0-9
Text1.MaxLength = 1
End Sub
Lägg sedan till tre klassmoduler.
Via projekt-menyn kan du lägga till tre klassmoduler. Markera sedan en i taget och byt namn på dem till clsBil, clsTraktor och clsCykel. Egenskaperna för klassmodulen får du fram genom att trycka F4.
clsBil
Option Explicit
Private Const Jag = "Jag är en bil"
Public Function Identifiera() As String
Identifiera = Jag
End Function
Public Function Ange_Hastighet() As Integer
Ange_Hastighet = Int(100 * Rnd) + 30
End Function
clsTraktor
Option Explicit
Private Const Jag = "Jag är en traktor"
Public Function Identifiera() As String
Identifiera = Jag
End Function
Public Function Ange_Hastighet() As Integer
Ange_Hastighet = Int(10 * Rnd) + 40
End Function
clsCykel
Option Explicit
Private Const Jag = "Jag är en cykel"
Public Function Identifiera() As String
Identifiera = Jag
End Function
Public Function Ange_Hastighet() As Integer
Ange_Hastighet = Int(10 * Rnd) + 30
End Function
Japp det var väl ungefär allt. När du nu kör detta exempel kommer 10 fordon (0-9) att skapas. Klicka på command1 för att slumpa fram ett fordon. Klicka på command2 för att identifiera fordonet och command3 för att få reda på dess hastighet. Oavsett om det är en cykel, bil eller traktor svarar det på samma interfacemetoder. Dock har respektive objekt implementerat sitt sätt att ange hastighet på tillexempel. Detta är "polymorfism".
Lektion 4. Händelser, (events)
Nu är det lagom att ta upp en annan kraftfull egenskap hos VB. Detta har dock inget med objhekt-orientering att göra, men det kan vara på sin plats att ändå ta upp detta nu.
Mycket i VB styrs ju av händelser som triggas när formar laddas, knappar klickas och textboxar ändras. Det finns så många händelser att de verkar förvirrande i början. Bara när du startar ditt program triggas fyra events på raken. Nämligen form_initialize, form_load, form_resize och form_activate. Inte nog att det är ett måste att veta vilka events som triggas när, du måste vet i vilken ordning också annars kan ditt program ofta bete sig rätt synnerligt.
När man håller på med events gäller det dock att se upp så man inte ställer till det för sig. Det finns risk att hamna i rekursiva event loopar. Säg att du har en form med en checkbox. när du ändrar dess värde så triggas eventet check_click(), om du i den subrutinen lägger kod för att ändra status på checkboxen kommer eventet att triggas igen. Du är inne i en rekursiv loop som tillslut kommer ge ett fel då minnet tar slut.
Betrakta följande kod:
Option Explicit
Private Sub Check1_Click()
Check1.Value = 1 - Check1.Value
End Sub
VB kan du givetvis skapa egna händelser. Detta är en mycket kraftfull egenskap. Jag skall med ett exempel visa hur du gör en enkel timer istället för att använda den befintliga. Starta ett nytt VB standard projekt. Lägg till en form1, command1, command2. Lägg dessutom till en klassmodul som du byter namn på till clsTimer.
Klistra in koden nedan och kör programmet. Kommentarer finns i koden.
Form1
Option Explicit
'Deklarera en variabel för clsTimer-objektet
'Ange i deklarationen att objektet innehåller
'events
Private WithEvents myTimer As clsTimer
Private Sub Command1_Click()
'Starta timern
myTimer.startTimer
End Sub
Private Sub Command2_Click()
'Stoppa timern
myTimer.stopTimer
End Sub
Private Sub Form_Load()
'Skapa en instans av timerobjektet och koppla
'en referens till det.
Set myTimer = New clsTimer
'Sätt timerobjektets intervall till 1 sekund
myTimer.Interval = 1000
End Sub
Private Sub myTimer_tick()
'Gör debugutskrift för varje gång som timerobjektets
'tick-event triggas.
Debug.Print "TICK-TACK"
End Sub
clsTimer
Option Explicit
'Deklarera händelsen som skall användas
Public Event Tick()
Private ticking As Boolean 'Lokal variabel
Private timerInterval As Integer 'Lokal variabel
Public Sub startTimer()
Dim s As Single 'Variabel för timern
ticking = True 'Variabel=true då timern tickar
While ticking = True 'Så länge som timern tickar
s = Timer 'Spar timer-tiden
'Så länge som tiden är mindre än starttid +
'TimerIntervallet så loopa. DoEvents låter
'Systemet exekvera viss kod. Annars verkar det
'Som systemet hänger sig.
While Timer < (s + timerInterval / 1000)
DoEvents
Wend
RaiseEvent Tick 'När tiden gått, trigga händelsen
Wend
End Sub
Public Sub stopTimer()
ticking = False
End Sub
Public Property Let Interval(millisekunder As Integer)
'Property gör så man kan tilldela egenskapen med
'likhetstecken. Interval=1000, hade det varit en
'subrutin (public sub) så hade det blivit interval 1000
timerInterval = millisekunder
End Property
Public Property Get Interval() As Integer
'Spara intervallet internt i objektet
Interval = timerInterval
End Property
Lycka till, fler lektioner kommer snart.
Jag planerar ytterligare lektioner och skall då höja svårighetsgraden lite och tillämpa de saker vi lärt oss ovan. Jag skall visa hur man på ett objektorienterat sätt kan simulera en klocka. Hur man identifierar de olika ingående objekten och omsätter dessa i kod.
Var denna artikeln användbar?
Om du gör någon intressant (eller kanske något konstigt fel) på grund av detta material så skicka gärna det med ett mail eller bifoga en länk till mig så presenterar jag detta som ytterligare exempelfiler för kursen. Om detta innehållet är felaktigt eller du lärt dig fler finesser så skriv gärna en rad eller varför inte en egen kurs baserat på dina erfarenheter. Sänd gärna in dina tips till denna kurs./Peter Holm
0 Kommentarer