Смекни!
smekni.com

VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования (стр. 68 из 72)

========357

Если Visual Basic заранее знает, с объектом какого типа он будет иметь дело, он может выполнить предварительные действия для того, чтобы более эффективно использовать объект. Если используется обобщенный (generic) объект, то программа не может выполнить подготовки, и в результате этого потеряет в производительности.

Программа Generic демонстрирует разницу в производительности между объявлением объектов как принадлежащих к определенному типу или как обобщенных объектов. Тест выполняется одинаково, за исключением того, что в одном из случаев объект определяется, как имеющий тип Object, а не тип SpecificClass. При этом установка значения данных объекта с использованием обобщенного объекта выполняется в 200 раз медленнее.

Private Sub TestSpecific()

Const REPS = 1000000 ' Выполнить миллион повторений.

Dim obj As SpecificClass

Dim i As Long

Dim start_time As Single

Dim stop_time As Single

Set obj = New SpecificClass

start_time = Timer

For i = 1 To REPS

obj.Value = I

Next i

stop_time = Timer

SpecificLabel.Caption = _

Format$(1000 * (stop_time - start_time) / REPS, "0.0000")

End Sub

Зарезервированное слово Implements

В 5‑й версии Visual Basic зарезервированное слово Implements (Реализует) позволяет программе использовать полиморфизм без использования обобщенных объектов. Например, программа может определить интерфейс Vehicle (Средство передвижения), Если классы Car (Автомобиль) и Truck (Грузовик) оба реализуют интерфейс Vehicle, то программа может использовать для выполнения функций интерфейса Vehicle объекты любого из двух классов.

Создадим вначале класс интерфейса, в котором определим открытые переменные, которые он будет поддерживать. В нем также должны быть определены прототипы открытых процедур для всех методов, которые он будет поддерживать. Например, следующий код демонстрирует, как класс Vehicle может определить переменную Speed (Скорость) и метод Drive (Вести машину):

Public Speed Long

Public Sub Drive()

End Sub

=======358

Теперь создадим класс, который реализует интерфейс. После оператора Option Explicit в секции Declares добавляется оператор Implements определяющий имя класса интерфейса. Этот класс должен также определять все необходимые для работы локальные переменные.

Класс Car реализует интерфейс Vehicle. Следующий код демонстрирует, как в нем определяется интерфейс и закрытая (private) переменная m_Speed:

Option Explicit

Implements Vehicle

Private m_Speed As Long

Когда к классу добавляется оператор Implements, Visual Basic считывает интерфейс, определенный указанным классом, а затем создает соответствующие заглушки в коде класса. В этом примере Visual Basic добавит новую секцию Vehicle в исходный код класса Car, и определит процедуры let и get свойства Vehicle_Speed для представления переменной Speed, определенной в интерфейсе Vehicle. В процедуре let Visual Basic использует переменную RHS, которая является сокращением от Right Hand Side (С правой стороны), в которой задается новое значение переменной.

Также определяется процедура Vehicle_Drive. Чтобы реализовать функции этих процедур, нужно написать код для них. Следующий код демонстрирует, как класс Car может определять процедуры Speed и Drive.

Private Property Let Vehicle_Speed(ByVal RHS As Long)

m_Speed = RHS

End Property

Private Property Get Vehicle_Speed() As Long

Vehicle_Speed = m_Speed

End Property

Private Sub Get Vehicle_Drive()

' Выполнить какие‑то действия.

:

End Property

После того, как интерфейс определен и реализован в одном или нескольких классах, программа может полиморфно использовать элементы в этих классах. Например, допустим, что программа определила классы Car и Track, которые оба реализуют интерфейс Vehicle. Следующий код демонстрирует, как программа может проинициализировать значения переменной Speed для объекта Car и объекта Truck.

Dim obj As Vehicle

Set obj = New Car

obj.Speed = 55

Set obj = New Truck

obj .Speed =45

==========359

Ссылка obj может указывать либо на объект Car, либо на объект Truck. Так как в обоих этих объектах реализован интерфейс Vehicle, то программа может оперировать свойством obj.Speed независимо от того, указывает ли ссылка obj на Car или Truck.

Так как ссылка obj указывает на объект, который реализует интерфейс Vehicle, то Visual Basic знает, что этот объект имеет процедуры, работающие со свойством Speed. Это означает, что он может выполнять вызовы процедур свойства Speed более эффективно, чем это было бы в случае, если бы obj была ссылкой на обобщенный объект.

Программа Implem является доработанной версией программы описанной выше программы Generic. Она сравнивает скорость установки значений с использованием обобщенных объектов, определенных объектов и объектов, которые реализуют интерфейс. В одном из тестов на компьютере с процессором Pentium с тактовой частотой 166 МГц, программе потребовалось 0,0007 секунды для установки значений при использовании определенного типа объекта. Для установки значений при использовании объекта, реализующего интерфейс, потребовалось 0,0028 секунды (в 4 раза больше). Для установки значений при использовании обобщенного объекта потребовалось 0,0508 секунды (в 72 раза больше). Использование интерфейса является не таким быстрым, как использование ссылки на определенный объект, но намного быстрее, чем использование обобщенных объектов.

Наследование и повторное использование

Процедуры и функции поддерживают повторное использование (reuse). Вместо того, чтобы каждый раз писать код заново, можно поместить его в подпрограмму, тогда вместо блока кода можно просто подставить вызов подпрограммы.

Аналогично, определение процедуры в классе делает ее доступной во всей программе. Программа может использовать эту процедуру, используя объект, который является экземпляром класса.

В среде программистов, использующих объектно‑ориентированный подход, под повторным использованием обычно подразумевается нечто большее, а именно наследование (inheritance). В объектно‑ориентированных языках, таких как C++ или Delphi, один класс может порождать (derive) другой. При этом второй класс наследует (inherits) всю функциональность первого класса. После этого можно добавлять, изменять или убирать какие‑либо функции из класса‑наследника. Это также является формой повторного использования кода, поскольку при этом программисту не нужно заново реализовать функции родительского класса, для того, чтобы использовать их в классе‑наследнике.

Хотя Visual Basic и не поддерживает наследование непосредственно, можно добиться примерно тех же результатов, используя ограничение (containment) или делегирование (delegation).[RP23] При делегировании объект из одного класса содержит экземпляр класса из другого объекта, и затем передает часть своих обязанностей заключенному в нем объекту.

Например, предположим, что имеется класс Employee, который представляет данные о сотрудниках, такие как фамилия, идентификационный номер в системе социального страхования и зарплата. Предположим, что нам теперь нужен класс Manager, который делает то же самое, что и класс Employee, но имеет еще одно свойство secretary (секретарь).

Для использования делегирования, класс Manager должен включать в себя закрытый объект типа Employee с именем m_Employee. Вместо прямого вычисления значений, процедуры работы со свойствами фамилии, номера социального страхования и зарплаты передают соответствующие вызовы объекту m_Employee. Следующий код демонстрирует, как класс Manager может оперировать процедурами свойства name (фамилия):

==========360

Private m_Employee As New Employee

Property Get Name() As String

Name = m_Employee.Name

End Property

Property Let Name (New_Name As String)

m_Employee.Name = New_Name

End Property

Класс Manager также может изменять результат, возвращаемый делегированной функцией, или выдавать результат сама. Например, в следующем коде показано, как класс Employee возвращает строку текста с данными о сотруднике.

Public Function TextValues() As String

Dim txt As String

txt = m_Name & vbCrLf

txt = txt & " " & m_SSN & vbCrLf

txt = txt & " " & Format$(m_Salary, "Currency") & vbCrLf

TextValues = txt

End Function

Класс Manager использует функцию TextValues объекта Employee, но добавляет перед возвратом информацию о секретаре в строку результата.

Public Function TextValues() As String

Dim txt As String

txt = m_Employee.TextValues

txt = txt & " " & m_Secretary & vbCrLf

TextValues = txt

End Function

Программа Inherit демонстрирует классы Employee и Manager. Интерфейс программы не представляет интереса, но ее код включает простые определения классов Employee и Manager.

Парадигмы ООП

В первой главе мы дали определение алгоритма как «последовательности инструкций для выполнения какого‑либо задания». Несомненно, класс может использовать алгоритмы в своих процедурах и функциях. Например, можно использовать класс для упаковки в него алгоритма. Некоторые из программ, описанных в предыдущих главах, используют классы для инкапсуляции сложных алгоритмов.

=========361

Классы также позволяют использовать новый стиль программирования, при котором несколько объектов могут работать совместно для выполнения задачи. В этом случае может быть бессмысленным задание последовательности инструкций для выполнения задачи. Более адекватным может быть задание модели поведения объектов, чем сведение задачи к последовательности шагов. Для того чтобы отличать такое поведение от традиционных алгоритмов, мы назовем их «парадигмами».

Следующие раздела описывают некоторые полезные объектно‑ориентированные парадигмы. Многие из них ведут начало из других объектно‑ориентированных языков, таких как C++ или Smalltalk, хотя они могут также использоваться в Visual Basic.

Управляющие объекты

Управляющие объекты (command) также называются объектами действия (action objects), функций (function objects) или функторами (functors). Управляющий объект представляет какое‑либо действие. Программа может использовать метод Execute (Выполнить) для выполнения объектом этого действия. Программе не нужно знать ничего об этом действии, она знает только, что объект имеет метод Execute.

Управляющие объекты могут иметь множество интересных применений. Программа может использовать управляющий объект для реализации: