Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка ООП.doc
Скачиваний:
23
Добавлен:
08.11.2018
Размер:
1.4 Mб
Скачать

Классы и объекты

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

Неформально объект может быть определен как осязаемая реальность, проявляющая четко выделяемое поведение. С точки зрения восприятия человеком объектом может быть:

  • осязаемый или видимый предмет,

  • нечто, воспринимаемое мышлением,

  • нечто, на что направлена мысль или действие.

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

Объект – нечто, обладающее состоянием, поведением и идентичностью; структура и поведение схожих объектов определяет общий для них класс; термины «экземпляр класса» и «объект» взаимозаменяемы.

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

Состояние объекта характеризуется перечнем (обычно статическим) всех свойств данного объекта и текущими (обычно динамическими) значениями каждого из этих свойств.

Перечень свойств объекта составляет неизменяемую основу объекта. Но в ряде случаев состав свойств объекта может изменяться. Пример – самообучающиеся системы.

Все свойства имеют некоторые значения – простые количественные характеристики или ссылки на другой объект. Причем другие объекты в свою очередь имеют свое внутренне состояние и могут его изменять.

Объекты не существуют изолированно, а подвергаются воздействию извне, или сами воздействуют на другие объекты.

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

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

Поведение объекта может быть выражено через операции.

Операция – это услуга, которую класс может предоставить своим клиентам. Наиболее распространенные операции:

  • модификатор – изменяет состояние объекта,

  • селектор – считывает состояние объекта, но не изменяет его,

  • итератор – позволяет организовать доступ ко всем частям объекта в строго определенной последовательности,

  • конструктор – создание объекта и/или его инициализация,

  • деструктор – освобождает состояние объекта и/или разрушает сам объект.

Чаще всего операции – это методы. Но возможно использование и свободных подпрограмм, которые также называют утилитами класса.. Рекомендуется использовать только методы, но возможны ситуации – например, если операция выполняется сразу над несколькими объектами разных классов – когда удержаться от искушения организовать операцию как свободную подпрограмму сложно.

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

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

Идентичность – это такое свойство объекта, которое отличает его от всех других объектов.

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

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

Также возможно, что два разных указателя в результате выполнения операции присваивания будут ссылаться на один и тот же объект – такую ситуацию называют структурной зависимостью. Структурная зависимость порождает в ООП много проблем: утечку памяти, неправильный доступ к памяти, непрогнозируемые изменения состояний и т.п.

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

Для ООП интерес представляют два типа отношений между объектами:

  • связи,

  • агрегация.

Связи определяются как физическое или концептуальное соединение между объектами. Объект сотрудничает с другими объектами через связи, соединяющие его с ними.

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

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

Объект может выполнять одну из следующих трех ролей:

  • Деятель – может воздействовать на другие объекты, но сам никогда не подвергается воздействию;

  • Сервер – может только подвергаться воздействию;

  • Агент – может выступать как в активной, так и в пассивной роли.

С проблемой установки связи между объектами связана проблема видимости.

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

Существуют следующие способы обеспечить видимость:

  • сервер глобален по отношению к клиенту,

  • сервер (или указатель на него) передан клиенту в качестве параметра операции,

  • сервер является частью клиента,

  • сервер локально порождается клиентом в ходе выполнения какой-либо операции.

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

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

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

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

Класс – это некое множество объектов, имеющих общую структуру и общее поведение.

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

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

Интерфейс класса может быть разделен на три части:

  • открытую – видимую всем клиентам;

  • защищенную – видимую самому классу, его подклассам и друзьям;

  • закрытую – видимую только самому классу и его друзьям.

Разные языки программирования предусматривают разные комбинации этих частей.

Отношения между классами: имеются следующие виды отношений:

  • ассоциация,

  • наследование,

  • агрегация,

  • использование,

  • инстацирование,

  • метакласс.

Наиболее общим из них является ассоциация. Обычно в процессе проектирования ассоциация уточняется и превращается в какую-либо иную связь.

Ассоциация означает, что есть какая-то связь, не уточняя ее характер. Ассоциация должна работать в обе стороны. Например, торговая точка: две абстракции – товары и продажи. Они связаны. Задавшись товаром, можно выйти на сделку когда он был продан и наоборот.

Реализация отношения типа ассоциация, означает, что классы должны содержать ссылки друг на друга.

Наследование – это такое отношение между классами, когда один класс повторяет структуру и поведение другого класса (одиночное наследование) или других классов (множественное наследование).

Наследование используется, если у объектов есть что-то общее или между ними есть смысловая ассоциация.

Наследование можно рассматривать как способ управления повторным использованием программ, то есть как простое решение разработчика о заимствовании полезного кода.

Наследование обычно предполагает наличие полиморфизма.

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

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

Для того чтобы понять, наследование или агрегация имеет место, следует задаться вопросом – имеет место отношение «быть чем-то» или «являться частью чего-то». В первом случае это – наследование, во втором – агрегация.

Использование. Отношение использования между классами соответствует аналогичной связи между их объектами – отношения клиент-сервер.

Инстацирование. При инстацировании разрабатывается обобщенный класс, который еще называют параметризованным. Он представляет собой что-то вроде шаблона для построения других классов. Пример – шаблоны классов в С++. Шаблон может быть параметризован другими классами, объектами или операциями. Т.е. какие-то части описания и реализации класса, которые могут отличаться, заменены обозначениями. Далее эти обозначения – параметры можно заменить на конкретные имена типов, процедур и т.д. с помощью например команд препроцессора. Естественно, что параметризованный класс не является синтаксически правильным.

Если класс порожден от параметризованного класса, то говорят что между ними отношение инстацирования.

Наследование вообще более мощный механизм и через наследование можно получить большинство преимуществ обобщенных классов, но не наоборот.

Метаклассы. Любой объект является экземпляром какого-либо класса. Что будет, если обращаться с классами как с объектами? Получится класс класса – метакласс. Пример – указатели на класс в Object Pascal. Также к возможностям метаклассов относится поддержка статических элементов класса в С++.