vbamania.pl
login:
hasło:
 
  *Rejestracja *Zapomniane hasło
 Dziś jest sobota, 20 kwietnia 2024 roku.
Ustaw jako stronę startową Ulubione Napisz
Artykuły
Klasa oNode
zamieszczony: 23 października 2003
przez: admin
czytany 20227 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