на тему рефераты
 
Главная | Карта сайта
на тему рефераты
РАЗДЕЛЫ

на тему рефераты
ПАРТНЕРЫ

на тему рефераты
АЛФАВИТ
... А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш Щ Э Ю Я

на тему рефераты
ПОИСК
Введите фамилию автора:


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


Создадим вначале класс интерфейса, в котором определим открытые переменные, которые он будет поддерживать. В нем также должны быть определены прототипы открытых процедур для всех методов, которые он будет поддерживать. Например, следующий код демонстрирует, как класс 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.

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

·         Настраиваемых элементов интерфейса;

·         Макрокоманд;

·         Ведения и восстановления записей;

·         Функций «отмена» и «повтор».

Чтобы создать настраиваемый интерфейс, форма может содержать управляющий массив кнопок. Во время выполнения программы форма может загрузить надписи на кнопках и создать соответствующий набор управляющих объектов. Когда пользователь нажимает на кнопку, обработчику событий кнопки нужно всего лишь вызвать метод Execute соответствующего управляющего объекта. Детали происходящего находятся внутри класса управляющего объекта, а не в обработчике событий.

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

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

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

И, наконец, программа может использовать набор управляющих объектов для реализации функций отмены (undo) и повтора (redo).

=========362

Программа использует переменную LastCmd для отслеживания последнего управляющего объекта в коллекции. Если вы выбираете команду Undo (Отменить) в меню Draw (Рисовать), то программа уменьшает значение переменной LastCmd на единицу. Когда программа потом выводит рисунок, она вызывает только объекты, стоящие до объекта с номером LastCmd.

Если вы выбираете команду Redo (Повторить) в меню Draw, то программа увеличивает значение переменной LastCmd на единицу. Когда программа выводит рисунок, она выводит на один объект больше, чем раньше, поэтому отображается восстановленный рисунок.

При добавлении новой фигуры программа удаляет любые команды из коллекции, которые лежат после позиции LastCmd,. затем добавляет новую команду рисования в конце и запрещает команду Redo, так как нет команд, которые можно было бы отменить. На рис. 13.1 показано окно программы Command2 после добавления новой фигуры.

Контролирующий объект

Контролирующий объект (visitor object) проверяет все элементы в составном объекте (aggregate object). Процедура, реализованная в составном классе, обходит все объекты, передавая каждый из них контролирующему объекту в качестве параметра.

Например, предположим, что составной объект хранит элементы в связном списке. Следующий код показывает, как его метод Visit обходит список, передавая каждый объект в качестве параметра методу Visit контролирующего объекта ListVisitor:

Public Sub Visit(obj As ListVisitor)

Dim cell As ListCell

    Set cell = TopCell

    Do While Not (cell Is Nothing)

        obj.Visit cell

        Set cell = cell.NextCell

    Loop

End Sub

@Рис. 13.1. Программа Command2

=========363

Следующий код демонстрирует, как класс ListVisitor может выводить на экран значения элементов в окне Immediate (Срочно).

Public Sub Visit(cell As ListCell)

    Debug.Print cell.Value

End Sub

Используя парадигму контролирующего объекта, составной класс определяет порядок, в котором обходятся элементы. Составной класс может определять несколько методов для обхода содержащих его элементов. Например, класс дерева может обеспечивать методы VisitPreorder (Прямой обход), VisitPostorder (Обратный обход), VisitInorder (Симметричный обход) и VisitBreadthFirst (Обход в глубину) для обхода элементов в различном порядке.

Итератор

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

Чтобы выполнить обход элементов, итератор должен представлять порядок, в котором элементы записаны, чтобы определить порядок их обхода. Если составной класс представляет собой связный список, то объект‑итератор должен знать, что элементы находятся в связном списке, и должен уметь перемещаться по списку. Так как итератору известны детали внутреннего устройства списка, это нарушает скрытие данных составного объекта.

Вместо того чтобы каждый класс, которому нужно проверять элементы составного класса, реализовал обход самостоятельно, можно сопоставить составному классу класс итератора. Класс итератора должен содержать простые процедуры MoveFirst (Переместиться в начало), MoveNext (Переместиться на следующий элемент), EndOfList (Переместиться в конец списка) и CurrentItem (Текущий элемент) для обеспечения косвенного доступа к списку. Новые классы могут включать в себя экземпляр класса итератора и использовать его методы для обхода элементов составного класса. На рис. 13.2 схематически показано, как новый объект использует объект‑итератор для связи со списком.

Программа IterTree, описанная ниже, использует итераторы для обхода полного двоичного дерева. Класс Traverser (Обходчик) содержит ссылку на объект‑итератор. Они использует обеспечиваемые итератором процедуры MoveFirst, MoveNext, CurrentCaption и EndOfTree для получения списка узлов в дереве.

@Рис. 13.2. Использование итератора для косвенной связи со списком

=========364

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

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

Дружественный класс

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

Дружественный класс (friend class) — это класс, имеющий специальное разрешение нарушать скрытие данных для другого класса. Например, класс итератора является дружественным классом для соответствующего составного класса. Ему, в отличие от других классов, разрешено нарушать скрытие данных для составного класса.

В 5‑й версии Visual Basic появилось зарезервированное слово Friend для разрешения ограниченного доступа к переменным и процедурам, определенным внутри модуля. Элементы, определенные при помощи зарезервированного слова Friend, доступны внутри проекта, но не в других проектах. Например, предположим, что вы создали классы LinkedList (Связный список) и ListIterator (Итератор списка) в проекте ActiveX сервера. Программа может создать сервер связного списка для управления связными списками. Порождающий метод класса LinkedList может создавать объекты типа ListIterator для использования в программе.

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

Этот очень эффективный, но довольно громоздкий метод. Она требует создания двух проектов, и установки одного сервера ActiveX. Он также не работает в более ранних версиях Visual Basic.

Наиболее простой альтернативой было бы соглашение о том, что только дружественные классы могут нарушать скрытие данных друг друга. Если все разработчики будут придерживаться этого правила, то проектом все еще можно будет управлять. Тем не менее, искушение обратиться напрямую к данным класса LinkedList может быть сильным, и всегда существует вероятность, что кто‑нибудь нарушит скрытие данных из‑за лени или по неосторожности.

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

=======365

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

Интерфейс

В этой парадигме один из объектов выступает в качестве интерфейса (interface) между двумя другими. Один объект может использовать свойства и методы первого объекта для взаимодействия со вторым. Интерфейс иногда также называется адаптером (adapter), упаковщиком (wrapper), или мостом (bridge). На рис. 13.3 схематически изображена работа интерфейса.

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

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

Фасад

Фасад (Facade) аналогичен интерфейсу, но он обеспечивает простой интерфейс для сложного объекта или группы объектов. Фасад также иногда называется упаковщиком (wrapper). На рис. 13.4. показана схема работы фасада.

Разница между фасадом и интерфейсом в основном умозрительная. Основная задача интерфейса — обеспечение косвенного взаимодействия между объектами, чтобы они могли развиваться независимо. Основная задача фасада — облегчение использования каких‑то сложных вещей за счет скрытия деталей.

Порождающий объект

Порождающий объект (Factory) — это объект, который создает другие объекты. Порождающий метод — это процедура или функция, которая создает объект.

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

@Рис. 13.3 Интерфейс

========366

@Рис. 13.4. Фасад

Программа IterTree создает полное двоичное дерево, записанное в массиве. После нажатия на одну из кнопок, задающих направление обхода, программа создает объект Traverser (Обходчик). Она также использует один из порождающих методов дерева для создания соответствующего итератора. Объект Traverser использует итератор для обхода дерева и вывода списка узлов в правильном порядке. На рис. 13.5 приведено окно программы IterTree, показывающее обратный обход дерева.

Единственный объект

Единственный объект (singleton object) — это объект, который существует в приложении в единственном экземпляре. Например, в Visual Basic определен класс Printer (Принтер). Он также определяет единственный объект с тем же названием. Этот объект представляет принтер, выбранный в системе по умолчанию. Так как в каждый момент времени может быть выбран только один принтер, то имеет смысл определить объект Printer как единственный объект.

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

@Рис. 13.5. Программа IterTree, демонстрирующая обратный обход

=======367

Программа WinList использует этот подход для создания единственного объекта класса WinListerClass. Объект класса WinListerClass представляет окна в системе. Так как операционная система одна, то нужен только один объект класса WinListerClass. Модуль WinList.BAS использует следующий код для создания единственного объекта с названием WindowLister.

Private m_WindowLister As New WindowListerClass

Property Get WindowLister() As WindowListerClass

    Set WindowLister = m_WindowLister

End Property

Единственный объект WindowLister доступен во всем проекте. Следующий код демонстрирует, как основная программа использует свойство WindowList этого объекта для вывода на экран списка окон.

WindowListText.Text = WindowLister.WindowList

Преобразование в последовательную форму

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

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

Страницы: 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


на тему рефераты
НОВОСТИ на тему рефераты
на тему рефераты
ВХОД на тему рефераты
Логин:
Пароль:
регистрация
забыли пароль?

на тему рефераты    
на тему рефераты
ТЕГИ на тему рефераты

Рефераты бесплатно, реферат бесплатно, курсовые работы, реферат, доклады, рефераты, рефераты скачать, рефераты на тему, сочинения, курсовые, дипломы, научные работы и многое другое.


Copyright © 2012 г.
При использовании материалов - ссылка на сайт обязательна.