Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
13
Добавлен:
26.03.2015
Размер:
130.05 Кб
Скачать
  1. Создание динамических классов

Рассмотрим классический пример и создадим линейный односвязный список. Для этого определим три класса, задающие:

  • информационную часть элемента списка;

  • структуру элемента списка;

  • сам список, в том числе и операции над ним.

Рассмотрим список, хранящий информацию о личностях.

Создадим вначале класс Личность.

(Смотри его в данном документе Сервис Макросредактор Visual Basic).

Option Explicit

' Создадим класс Личность

' Свойства класса: имя, отчество, фамилию, дату рождения

' Закроем от прямого доступа,

' получить и изменить их можно только через методы класса

Private Имя As String

Private Отчество As String

Private Фамилия As String

Private ДатаРождения As Date

Public Sub InitPerson(ByVal FN As String, ByVal LN As String, _

ByVal DoB As Date)

'Инициализация личности

Имя = FN

Фамилия = LN

ДатаРождения = DoB

End Sub

Public Sub PrintPerson()

'Печать в отладочном окне

Dim s As String

If WhoIs Then s = "родилась" Else s = "родился"

Debug.Print Имя, Отчество, Фамилия, s, ДатаРождения

End Sub

Public Sub CopyPerson(You As Личность)

Имя = You.ВашеИмя

Фамилия = You.ВашаФамилия

ДатаРождения = You.ВашаДатаРождения

End Sub

Public Function WhoIs() As Boolean

' Пытается определить пол личности, анализируя имя и фамилию

' Возвращает True, если думает, что имеет дело с женщиной.

Dim F1 As Boolean, F2 As Boolean

F1 = ПоследняяБуква(Имя) = "А" Or ПоследняяБуква(Имя) = "Я"

F2 = ПоследняяБуква(Фамилия) = "А" Or ПоследняяБуква(Фамилия) = "Я"

If F1 And F2 Then

' можно полагать, что наша Личность - женщина

WhoIs = True

ElseIf Not F1 And F2 Then

WhoIs = False

Else 'Есть сомнения

If Отчество = "" Then

Отчество = InputBox(Имя & " " & Фамилия & "! " & _

"Назовите отчество, пожалуйста.")

End If

WhoIs = ПоследняяБуква(Отчество) = "А"

End If

End Function

Public Sub SayWhoIs()

'Вывод сообщения о поле и возрасте личности

If WhoIs Then

MsgBox ("Думаю, " & Имя & _

", Вы из прекрасной половины человечества!")

ElseIf Year(ДатаРождения) > 1967 Then

MsgBox ("Думаю, " & Имя & ", Вы - молодой человек!")

Else

MsgBox ("Думаю, " & Фамилия & " - мужчина!")

End If

End Sub

Private Function ПоследняяБуква(ByVal W As String) As String

' Внутренняя функция: возвращает в верхнем регистре

' последнюю букву слова W

ПоследняяБуква = UCase(Right(W, 1))

End Function

Public Property Get ВашеИмя() As String

ВашеИмя = Имя

End Property

Public Property Let ВашеИмя(ByVal vNewValue As String)

Имя = vNewValue

End Property

Public Property Get ВашеОтчество() As String

ВашеОтчество = Отчество

End Property

Public Property Let ВашеОтчество(ByVal vNewValue As String)

Отчество = vNewValue

End Property

Public Property Get ВашаФамилия() As String

ВашаФамилия = Фамилия

End Property

Public Property Let ВашаФамилия(ByVal vNewValue As String)

Фамилия = vNewValue

End Property

Public Property Get ВашаДатаРождения() As Date

ВашеОтчество = Отчество

End Property

Public Property Let ВашаДатаРождения(ByVal vNewValue As Date)

ДатаРождения = vNewValue

End Property

Private Sub Class_Initialize()

Имя = "Адам"

Фамилия = "Человек"

ДатаРождения = #1/1/100#

End Sub

Теперь создадим класс с именем ЭлементСпискаЛичностей, задающий структуру элемента (запись). Этот класс прост, поскольку элементы односвязного списка состоят из двух полей – информационного и поля указателя соседнего элемента. Никакие методы над этим классом обычно не определяются.

Его полное описание:

' Класс ЭлементСпискаЛичностей содержит только два поля

Public Сам As Личность

Public Друг As ЭлементСпискаЛичностей

В определении класса ЭлементСпискаЛичностей свойство Друг является объектом того же класса. VB допускает такую рекурсию в определении.

Определим теперь класс СписокЛичностей, задающий сам список. Главное на данном этапе спроектировать операции над списком. Ограничимся набором традиционных методов:

AddFirst (F as Личность) - добавляет элемент в начало списка;

AddLastFirst (F as Личность) - добавляет элемент в конец списка;

Initializeконструктор по умолчанию, инициализирует список;

PrintList() – печатает содержимое элементов списка;

ClearList() - очищает список.

Таким образом, для построения списка необходимы минимум два указателя – на начало и конец списка: First и Last. Эти свойства закроем от внешнего использования. Добавим к ним открытую переменную Count, следящую за числом элементов списка. Приведем описание свойств и методов этого класса:

Option Explicit

' Определение класса СписокЛичностей

' Свойства

Private First As ЭлементСпискаЛичностей

Private Last As ЭлементСпискаЛичностей

Public Count As Integer

' Методы

Private Sub class_initialize()

Set First = Nothing

Set Last = Nothing

Count = 0

End Sub

Public Sub addfirst(F As Личность)

Dim Elem As New ЭлементСпискаЛичностей

Dim Info As New Личность

' Создаем копию переменной F. В списке будем использовать копию, а не ссылку

Info.CopyPerson F

Set Elem.Сам = Info

Set Elem.Друг = First

If First Is Nothing Then

Set Last = Elem

End If

Set First = Elem

Count = Count + 1

End Sub

Public Sub printlist()

Dim P As ЭлементСпискаЛичностей

Dim Q As Личность

Set P = First

While Not (P Is Nothing)

Set Q = P.Сам

Q.PrintPerson

Set P = P.Друг

Wend

End Sub

Public Sub AddLast(F As Личность)

Dim Elem As New ЭлементСпискаЛичностей

Dim Info As New Личность

' Создаем копию переменной F. В списке будем использовать копию, а не ссылку

Info.CopyPerson F

Set Elem.Сам = Info

Set Elem.Друг = Nothing

If First Is Nothing Then

Set First = Elem

Else

Set Last.Друг = Elem

End If

Set Last = Elem

Count = Count + 1

End Sub

Public Sub clearlist()

' Попытка освободить память не достигает успеха из-за отсутствия

' соответствующего оператора.

Dim P As ЭлементСпискаЛичностей, R As ЭлементСпискаЛичностей

Dim Q As Личность

Set P = First

While Not (P Is Nothing)

Set Q = P.Сам

' unload Q

Set R = P

Set P = P.Друг

' unload R

Wend

' Обнуление указателей

Set First = Nothing

Set Last = Nothing

Count = 0

End Sub

Приведем теперь простой пример, позволяющий построить список в процессе диалога с пользователем и в конце распечатать данные, хранящиеся в построенном списке.

Public Sub ВводСписка()

' Создание списка в диалоге с пользователем

Dim Личности As New СписокЛичностей

Dim ЭтоЛичность As New Личность

Dim Имя As String, Фамилия As String, Дата As Date

If MsgBox("Начнем создавать список личностей?", vbYesNo) = vbYes Then

Do

ЭтоЛичность.ВашеИмя = InputBox("Введите имя личности")

ЭтоЛичность.ВашаФамилия = InputBox("Введите фамилию ")

ЭтоЛичность.ВашаДатаРождения = InputBox("Введите дату рождения ")

Личности.AddLast ЭтоЛичность

Loop Until MsgBox("Продолжим создавать список личностей?", vbYesNo) = vbNo

Личности.printlist

End If

End Sub