Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОСНОВЫ ОФИСНОГО ПРОГРАММИРОВАНИЯ И ЯЗЫК VBA - 1....doc
Скачиваний:
59
Добавлен:
17.12.2018
Размер:
1.88 Mб
Скачать

Проект "Люди и Машины"

Проектирование семейства классов, как правило, начинают с проектирования схемы, задающей иерархию и связи в семействе, определения прародителей, определяющих базовые свойства и поведение. Приведем в качестве примера семейство классов, объектами которого будут Люди и машины. Вот одна из возможных схем, определяющая классы этого семейства и отношения между ними.

Рис. 5.3.  Схема семейства классов "Люди и Машины"

Мы не станем давать полную реализацию этой схемы. Для наших целей достаточно ограничиться ее частичной реализацией, где будут два родителя, имеющие общего потомка. У нас уже построен класс Личность, - пусть он и будет одним из родительских классов. Другим базовым родительским классом пусть будет класс Машина, задающий машины. Потомком этих двух родительских классов будет класс ВладелецМашины. Он наследует интерфейсы класса Личность и класса Машина. Поэтому объекты этого класса смогут входить и обрабатываться в разных группах, - в группе личностей и в группе машин. В нашем примере родительские классы не будут абстрактными. Напомним, что определенный в предыдущей лекции класс Личность является классом с событиями, так что его объекты могут реагировать на некоторые события, происходящие с ними. Мы не будем повторять здесь его описание. Класс Машина будет достаточно простым. Вот его определение:

Option Explicit

'Класс Машина

'Свойства класса

Private Марка As String

Private ДатаВыпуска As Date

Private Цвет As String

'Конструкторы класса

Private Sub Class_Initialize()

Марка = "Форд"

ДатаВыпуска = "20.07.1925"

Цвет = "Вишневый"

End Sub

Public Sub НоваяМашина(M As String, D As Date, C As String)

Марка = M

ДатаВыпуска = D

Цвет = C

End Sub

'Методы класса

Public Sub PrintDataCar()

Debug.Print "Марка = ", Марка

Debug.Print "ДатаВыпуска = ", ДатаВыпуска

Debug.Print "Цвет = ", Цвет

End Sub

Public Property Get МаркаМашины() As String

МаркаМашины = Марка

End Property

Public Property Get ЦветМашины() As String

ЦветМашины = Цвет

End Property

Public Property Get ДатаВыпускаМашины() As Date

ДатаВыпускаМашины = ДатаВыпуска

End Property

Пример 5.4. (html, txt)

У класса Машина имеется:

  • три закрытых свойства, обладающие статусом Read only,

  • два конструктора, - закрытый конструктор по умолчанию и открытый конструктор НоваяМашина,

  • один типичный для классов открытый метод, задающий печать свойств - PrintDataCar

Интерфейс класса составляют два открытых метода, они и будут наследоваться классом - потомком. Класс - потомок ВладелецМашины значительно больше унаследует от своего другого родителя - класса Личность. Вот определение класса ВладелецМашины:

Option Explicit

'Класс ВладелецМашины

'Наследует интерфейсы классов Личность и Машина

Implements Машина

Implements Личность

'Свойства класса

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

Private ЕгоМашина As Машина

Private Sub Class_Initialize()

Set Сам = New Личность

Set ЕгоМашина = New Машина

End Sub

'Реализация интерфейсов класса Личность

Private Sub Личность_CopyPerson(You As Личность)

Сам.CopyPerson (You)

End Sub

Private Sub Личность_InitPerson(ByVal FN As String, ByVal LN As String, ByVal DoB As Date)

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

Сам.InitPerson FN, LN, DoB

End Sub

Private Sub Личность_PrintPerson()

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

Сам.PrintPerson

End Sub

Private Sub Личность_SayWhoIs()

' Вывод сообщения о поле и возрасте владельца машины

Dim StrMsg As String

StrMsg = "Думаю, Владелец машины марки: " & _

ЕгоМашина.МаркаМашины & " это - "

If Сам.WhoIs Then

If Year(Сам.ВашаДатаРождения) > 1967 Then

StrMsg = StrMsg & "молодая девушка!"

Else: StrMsg = StrMsg & "женщина!"

End If

Else

If Year(Сам.ВашаДатаРождения) > 1967 Then

StrMsg = StrMsg & "молодой человек!"

Else: StrMsg = StrMsg & "мужчина!"

End If

End If

MsgBox (StrMsg)

End Sub

Private Function Личность_WhoIs() As Boolean

Сам.WhoIs

End Function

Private Property Let Личность_ВашаДатаРождения(ByVal NewValue As Date)

Сам.ВашаДатаРождения = NewValue

End Property

Private Property Get Личность_ВашаДатаРождения() As Date

'Зажигает событие ДеньРождения

'в зависимости от значения текущей даты

Личность_ВашаДатаРождения = Сам.ВашаДатаРождения

End Property

Private Property Let Личность_ВашаФамилия(ByVal NewValue As String)

'Зажигает событие ИзменениеФамилии

Сам.ВашаФамилия = NewValue

End Property

Private Property Get Личность_ВашаФамилия() As String

Личность_ВашаФамилия = Сам.ВашаФамилия

End Property

Private Property Let Личность_ВашеИмя(ByVal NewValue As String)

Сам.ВашеИмя = NewValue

End Property

Private Property Get Личность_ВашеИмя() As String

Личность_ВашеИмя = Сам.ВашеИмя

End Property

Private Property Let Личность_ВашеОтчество(ByVal NewValue As String)

Сам.ВашеОтчество = NewValue

End Property

Private Property Get Личность_ВашеОтчество() As String

Личность_ВашеОтчество = Сам.ВашеОтчество

End Property

'Реализация интерфейсов класса Машина

Private Property Get Машина_ДатаВыпускаМашины() As Date

Машина_ДатаВыпускаМашины = ЕгоМашина.ДатаВыпускаМашины

End Property

Private Property Get Машина_МаркаМашины() As String

Машина_МаркаМашины = ЕгоМашина.МаркаМашины

End Property

Private Property Get Машина_ЦветМашины() As String

Машина_ЦветМашины = ЕгоМашина.ЦветМашины

End Property

Private Sub Машина_PrintDataCar()

ЕгоМашина.PrintDataCar

End Sub

Private Sub Машина_НоваяМашина(M As String, D As Date, C As String)

ЕгоМашина.НоваяМашина M, D, C

End Sub

'Собственный интерфейс класса ВладелецМашины

'Public методы - интерфейс Владельца машины

Public Sub InitCarOwner(FN As String, LN As String, DoB As Date, _

Marka As String, DB As Date, Color As String)

'Инициализация данных о хозяине и его машине

Личность_InitPerson FN, LN, DoB

Машина_НоваяМашина Marka, DB, Color

End Sub

Public Sub ConnectOwnerAndCar(pers As Личность, car As Машина)

'соединяет данные о хозяине и его новой машине

Сам.CopyPerson pers

Машина_НоваяМашина car.МаркаМашины, car.ДатаВыпускаМашины, _

car.ЦветМашины

End Sub

Public Sub PrintOwnerData()

Личность_PrintPerson

Debug.Print " владеет машиной: "

Машина_PrintDataCar

End Sub

Пример 5.5. (html, txt)

Прокомментируем этот довольно длинный текст. Вот на какие моменты следует обратить внимание:

  1. Для того, чтобы реализовать полноценное наследование свойств и поведения родителей, а не только наследование интерфейсов, используется встраивание, - в классе определены свойства Сам класса Личность и свойство ЕгоМашина класса Машина.

  2. В конструкторе по умолчанию Class_Initialize, вызываемом при создании объекта класса ВладелецМашины, объекты Сам и ЕгоМашина инициализируются, - будут вызваны их конструкторы по умолчанию класса Личность и класса Машина.

  3. При наследовании интерфейсов класса Личность почти для всех методов наследовалось поведение родительского класса. Реализуется это достаточно просто - вызывается соответствующий метод объекта Сам.

  4. Для метода SayWhoIs поведение переопределено. В данном случае при вызове метод учитывает специфику класса и сообщает некоторые данные, как о владельце, так и о его машине. Так что при вызове этого метода у просто личностей и у личностей, являющихся владельцами машин, результат будет различным.

  5. Поскольку родительский класс допускает события, то и у потомка при вызове методов зажигаются соответствующие события.

  6. Интерфейс класса Машина реализуется подобным образом. Полностью наследуется поведение родительского класса.

  7. Собственный интерфейс класса довольно прост. У объектов этого класса нет новых дополнительных свойств, - все спрятано в свойствах встроенных объектов Сам и ЕгоМашина. Интерфейс составляют два конструктора и метод, осуществляющий печать данных. Обратите внимание, один конструктор InitCarOwner позволяет сконструировать новый объект класса по терминальным данным, характеризующим личность и его машину. Второй конструктор ConnectOwnerAndCar в качестве параметров использует ранее созданные объекты классов Личность и Машина, соединяя эти два объекта в один объект класса ВладелецМашины.