Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
A01_Metaphor.doc
Скачиваний:
6
Добавлен:
12.11.2019
Размер:
762.37 Кб
Скачать

Контрольные вопросы

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

2) Какими приемами можно обеспечить видимость между двумя объектами?

3) Какие существуют три подхода к синхронизации связи между объектами?

4) Сформулируйте своими словами понятие «агрегация» между двумя объектами.

5) Приведите примеры объектов, между которыми существуют отношения связи и агрегации.

1.3. Классы

1.3.1. Понятие класса. Понятия класса и объекта настолько тесно связаны, что невозможно говорить об объекте безотносительно к его классу. Однако существует важное различие этих двух понятий. В то время как объект обозначает конкретную сущность, определенную во времени и в пространстве, класс определяет лишь абстракцию существенного в объекте. Таким образом, можно говорить о классе «Млекопитающие», который включает характеристики, общие для всех млекопитающих. Для указания на конкретного представителя млекопитающих (кот Тютька) необходимо сказать «кот Тютька – млекопитающее».

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

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

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

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

  1. вводится понятие основы, которой можно сопоставлять некоторые множества;

  2. вводятся операции, которые делятся на два вида – конструкторы и анализаторы; с помощью конструкторов мы можем формально построить элементы сопоставляемого основе множества; с помощью анализаторов мы можем сделать оценку свойств элементов сопоставляемого основе множества;

  3. вводится описание свойств сопоставляемого основе множества; с помощью свойств мы выделяем интересующие нас подмножества;

  4. вводятся правила построения иерархической системы абстрактных типов данных.

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

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

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

1.3.2. Интерфейс и реализация. Рассмотрим идею контрактного программирования: большие задачи надо разделить на много маленьких и перепоручить их мелким субподрядчикам. Нигде эта идея не проявляет себя так ярко, как в проектировании классов.

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

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

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

  • открытую (public) - видимую всем клиентам без ограничений;

  • защищенную (protected) - видимую самому классу и его подклассам;

  • закрытую (private) - видимую только самому классу.

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

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

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

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

TDisplayItem objItem;

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

Свойства, составляющие представление класса, известны под разными именами. В большинстве языков программирования их называют полями.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]