скачать рефераты
  RSS    

Меню

Быстрый поиск

скачать рефераты

скачать рефератыРеферат: VB, MS Access, VC++, Delphi, Builder C++ принципы(технология), алгоритмы программирования

Инкапсуляция

Объект, определенный при помощи класса, заключает в себе данные, которые он содержит. Другие части программы могут использовать объект для оперирования его данными, не зная о том, как хранятся или изменяются значения данных. Объект предоставляет открытые (public) процедуры, функции, и процедуры изменения свойств, которые позволяют программе косвенно манипулировать или просматривать данные. Так как при этом данные являются абстрактными с точки зрения программы, это также называется абстракцией данных (data abstraction).

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

=========355

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

Например, предположим, что имеется класс FileDownload, который скачивает файлы из Internet. Программа сообщает классу FileDownload положение объекта, а объект возвращает строку с содержимым файла. В этом случае программе не требуется знать, каким образом объект производит загрузку файла. Он может скачивать файл, используя модемное соединение или соединение по выделенной линии, или даже извлекать файл из кэша на локальном диске. Программа знает только, что объект возвращает строку после того, как ему передается ссылка на файл.

Обеспечение инкапсуляции

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

Чтобы обеспечить доступ к данным, класс должен использовать процедуры для работы со свойствами. Например, следующие процедуры позволяют другим частям программы просматривать и изменять значение DegreesF объекта Temperature.

Private m_DegreesF As Single      ' Градусы Фаренгейта.

Public Property Get DegreesF() As Single

    DegreesF = m_DegreesF

End Property

Public Property Let DegreesF(new_DegreesF As Single)

    m_DegreesF = new_DegreesF

End Property

Различия между этими процедурами и определением m_DegreesF как открытой переменной пока невелики. Тем не менее, использование этих процедур позволяет легко изменять класс в дальнейшем. Например, предположим, что вы решите измерять температуру в градусах Кельвина, а не Фаренгейта. При этом можно изменить класс, не затрагивая остальных частей программы, в которых используются процедуры свойства DegreesF. Можно также добавить код для проверки ошибок, чтобы убедиться, что программа не попытается передать объекту недопустимые значения.

Private m_DegreesK As Single      ' Градусы Кельвина.

Public Property Get DegreesF() As Single

    DegreesF = (m_DegreesK - 273.15) * 1.8

End Property

Public Property Let DegreesF(ByVal new_DegreesF As Single)

Dim new_value As Single

    new_value = (new_DegreesF / 1.8) + 273.15

    If new_value < 0 Then

        ' Сообщить об ошибке ‑ недопустимое значении.

        Error.Raise 380, "Temperature", _

        "Температура должна быть неотрицательной."

    Else

        m_DegreesK = new_value

    End If

End Property

======357

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

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

Во‑вторых, многие программы демонстрируют методы работы со структурами данных. Например, сетевые алгоритмы, описанные в 12 главе, непосредственно используют данные объекта. Указатели, которые связывают узлы в сети друг с другом, составляют неотъемлемую часть алгоритмов. Было бы бессмысленно менять способ хранения этих указателей.

И, наконец, благодаря использованию открытых значений данных, код становится проще. Это позволяет вам сконцентрироваться на алгоритмах, и этому не мешают лишние процедуры работы со свойствами.

Полиморфизм

Второе преимущество объектно‑ориентированного программирования — это полиморфизм (polymorphism), что означает «имеющий множество форм». В Visual Basic это означает, что один объект может иметь различный формы в зависимости от ситуации. Например, следующий код представляет собой подпрограмму, которая может принимать в качестве параметра любой объект. Объект obj может быть формой, элементом управления, или объектом определенного вами класса.

Private Sub ShowName(obj As Object)

    MsgBox TypeName(obj)

End Sub

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

========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.

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48


Новости

Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

  скачать рефераты              скачать рефераты

Новости

скачать рефераты

© 2010.