przez:
admin
czytany 25990 razy.
W poprzednim punkcie kursu mówiłem sporo o obiektach. Dziś pora
na pierwszą prawdziwą klasę - czyli przepis na obiekt.
Klasa nasza będzie węzłem w grafie zwanym drzewem.
Graf to pojęcie z matematyki wyższej bardzo użyteczne w wielu dziedzinach nauki
i techniki. Grafem - drzewem jest na przykład struktura katalogów na dysku
twardym.
Na poniższym rysunku narysowane jest przykładowe drzewo.
Posiada ono sześć wierzchołków wzajemnie ze sobą powiązanych. Możemy
powiedzieć, że na przykład wierzchołek o nazwie węzeł 3 ma trzech
potomków - węzeł 4, węzeł 5 i węzeł 6.
Rodzicem tego wierzchołka jest natomiast węzeł 1. Węzeł 1
z kolei nie posiada rodzica:(. Taki wierzchołek nazywamy w teorii grafów
korzeniem. Każdy wierzchołek ma przyporządkowaną kolekcję potomków, z tym, że
czasami ta kolekcja nie posiada elementów.
Utwórzymy więc klasę, która będzie posiadać wszelkie cechy takiego wierzchołka.
Powinna ona posiadać następujące atrybuty:
- rodzica - który również jest węzłem,
- kolekcję potomków,
- wartość - w której będzie zapisana informacja identyfikująca taki węzeł,
Atrybuty te będziemy nazywać właściwościami.
Przydatne były by też funkcje, które informowałyby o tym, czy dany wierzchołek
jest bratem, czy jest rodzicem innego wierzchołka, czy dany wierzchołek jest
korzeniem itd. Funkcje te zdefiniowane w Property Get,
Property Let i Property Set również są
właściwościami naszej klasy
Z teorii programowania obiektowego wiemy też, że oprócz właściwości każdy
obiekt powinien udostępniać jakieś operacje które można na nim wykonać.
Operacje te nazywamy metodami.
Przydatnymi metodami w naszym przykładzie byłyby:
- dodawanie potomka,
- usuwanie potomka,
- zmiana rodzica itd.
Wstawmy więc do naszego projektu VBA nowy moduł klasy i nazwijmy go oNode. Jak
to zrobić przeczytacie w poprzedniej lekcji.
A oto pełny kod naszej klasy:
Private oParent As oNode
Private oValue As
String
Private oChildren As Collection
Private Sub Class_Initialize()
'konstruktor - procedura uruchamiana
'w momencie tworzenia instacji klasy
oValue = ""
Set oChildren = New
Collection
End Sub
Private Sub Class_Terminate()
'destruktor - procedura uruchamiana
'w momencie niszczenia instacji klasy
Set oChildren = Nothing
End Sub
Public Sub RemoveChild(oC
As oNode)
'Usuwanie dziecka
Dim el As oNode
Dim i As Long
i = 1
'przebiegamy po kolekcji potomków obiektu
'i jeśli obiekt będący argumentem procedury właściwości
'jest w kolekcji potomków obiektu to go usuwamy
For Each el In
Children
If el Is oC Then
Children.Remove i: Exit For
i = i + 1
Next el
End Sub
Friend Property
Get Children() As Collection
'Ustawienie referencji do kolekcji dzieci
Set Children = oChildren
End Property
Friend Property
Get Parent() As oNode
'Właściwość zwracająca rodzica obiektu
Set Parent = oParent
End Property
Property Set Parent(oC
As oNode)
'Metoda zmieniająca rodzica obiektu
If Not oParent
Is Nothing Then oParent.RemoveChild
Me
'ustawiamy nowego rodzica...
Set oParent = oC
'...i dodajemy obiekt do kolekcji potomków.
oC.Children.Add Me
End Property
Property Get Value()
As String
'Właściwość zwracająca wartość obiektu
Value = oValue
End Property
Property Let Value(strValue
As String)
'Właściwość ustawiająca wartość obiektu
oValue = strValue
End Property
Friend Function AddChild(strValue
As String) As oNode
'Metoda dodająca do nowego potomka do
'zbioru potomków danego obiektu
Dim oChild As
oNode
Set oChild = New
oNode
oChild.Value = strValue
Set oChild.Parent = Me
Set AddChild = oChild
End Function
Friend Property
Get ChildrenCount() As Long
'Właściwość zwracająca informację o liczbie
dzieci danego obiektu
ChildrenCount = Me.Children.Count
End Property
Friend Property
Get IsParent(oChild As oNode)
As Boolean
'Właściwość zwracająca informację, czy
'obiekt jest rodzicem obiektu danego jako argument
Dim oC As oNode
IsParent = False
For Each oC In
Children
If oC Is oChild Then
IsParent = True
Exit Property
End If
Next oC
End Property
Friend Property
Get IsChild(oParent As oNode)
As Boolean
'Właściwość zwracająca informację, czy
'obiekt jest potomkiem obiektu danego jako
argument
If Me.Parent Is oParent
Then IsChild = True Else
IsChild = False
End Property
Friend Property
Get IsBrother(oC As oNode) As
Boolean
'Właściwość zwracająca informację, czy
'obiekt ma rodzeństwo (czyli czy jego rodzic
ma inne dzieci)
If Me.Parent Is oC.Parent
And Not Me Is oC Then
IsBrother = True Else IsBrother
= False
End Property
Friend Property
Get IsRoot() As Boolean
'Właściwość zwracająca informację, czy
'obiekt jest korzeniem (czy nie ma rodzica)
If Me.Parent Is Nothing
Then IsRoot = True
Else IsRoot = False
End Property
Wstawmy teraz do naszego projektu zwykły moduł i pobawmy się w
tworzenie obiektów i operacje na nich.
Będziemy do tego wykorzystywać metody zdefiniowane przez nas w ciele klasy
oNode.
Wpiszmy do wstawionego modułu następującą procedurę, która zamodeluje drzewo
przedstawione na początku lekcji.
Sub drzewo()
Dim w1 As oNode
Dim w2 As oNode
Dim w3 As oNode
Dim w4 As oNode
Dim w5 As oNode
Dim w6 As oNode
'Wstawiamy pierwszy węzeł.
Set w1 = New oNode
w1.Value = "węzeł 1"
'wstawiamy mu potomków i odpowiednio nazywamy
Set w2 = w1.AddChild("węzeł 2")
Set w3 = w1.AddChild("węzeł 3")
'węzeł 3 ma też potomków
Set w4 = w3.AddChild("węzeł 4")
Set w5 = w3.AddChild("węzeł 5")
Set w6 = w3.AddChild("węzeł 6")
'A tu powypisujemy różne funkcje:
'Czy węzeł 1 jest korzeniemą
Dim strInfo As String
Dim w As oNode
'w- zmienna pomocnicza, raz ją ustawiamy na w1 a raz na w2
Set w = w1
'Set w = w2
If w1.IsRoot Then
strInfo = w.Value & " jest korzeniem."
Else
strIfo = w.Value & " nie jest korzeniem."
End If
MsgBox strInfo
Set w = Nothing
'czy w2 jest rodzicem w3?
MsgBox "Czy " & w2.Value & " jesst rodzicem " &
w3.Value & ": " & w2.IsParent(w3)
'czy w5 jest potomkiem w3?
MsgBox "Czy " & w5.Value & " jest potomkiem " &
w3.Value & ": " & w5.IsChild(w3)
'ilu potomków ma w3?
MsgBox w3.Value & " ma " & w3.Children.Count & "
potomków."
'usuwamy potomka w5 z kolekcji potomków w3
w3.RemoveChild w5
'ilu potomków teraz ma w3?
MsgBox "A teraz " & w3.Value & " ma " &
w3.Children.Count & " potomków."
'zwalniamy pamięć zajetą przez zmienne obiektowe
Set w1 = Nothing
Set w2 = Nothing
Set w3 = Nothing
Set w4 = Nothing
Set w5 = Nothing
Set w6 = Nothing
End Sub
To wszystko na dziś. Spróbujcie sami się pobawić w tworzenie
obiektów tej klasy. Miłej zabawy!
wstecz