Основы объектно-ориентированного программирования - Бертран Мейер
0/0

Основы объектно-ориентированного программирования - Бертран Мейер

Уважаемые читатели!
Тут можно читать бесплатно Основы объектно-ориентированного программирования - Бертран Мейер. Жанр: Прочая околокомпьтерная литература. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги Основы объектно-ориентированного программирования - Бертран Мейер:
Фундаментальный учебник по основам объектно-ориентированного программирования и инженерии программ. В книге подробно излагаются основные понятия объектной технологии – классы, объекты, управление памятью, типизация, наследование, универсализация. Большое внимание уделяется проектированию по контракту и обработке исключений, как механизмам, обеспечивающим корректность и устойчивость программных систем.В книге Бертрана Мейера рассматриваются основы объектно-ориентированного программирования. Изложение начинается с рассмотрения критериев качества программных систем и обоснования того, как объектная технология разработки может обеспечить требуемое качество. Основные понятия объектной технологии и соответствующая нотация появляются как результат тщательного анализа и обсуждений. Подробно рассматривается понятие класса - центральное понятие объектной технологии. Рассматривается абстрактный тип данных, лежащий в основе класса, совмещение классом роли типа данных и модуля и другие аспекты построения класса. Столь же подробно рассматриваются объекты и проблемы управления памятью. Большая часть книги уделена отношениям между классами – наследованию, универсализации и их роли в построении программных систем. Важную часть книги составляет введение понятия контракта, описание технологии проектирования по контракту, как механизма, обеспечивающего корректность создаваемых программ. Не обойдены вниманием и другие важные темы объектного программирования – скрытие информации, статическая типизация, динамическое связывание и обработка исключений. Глубина охвата рассматриваемых тем делает книгу Бертрана Мейера незаменимой для понимания основ объектного программирования.
Читем онлайн Основы объектно-ориентированного программирования - Бертран Мейер

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 137 138 139 140 141 142 143 144 145 ... 188

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

Что означает это отношение?

[x]. Если рассматривать значения каждого типа, то это отношение является просто отношением включения множеств: собаки образуют подмножество множества животных, экземпляры класса RECTANGLE образуют подмножество экземпляров класса POLYGON. (Это следует из определения "экземпляра" в начале этой лекции, заметим, что прямой экземпляр класса RECTANGLE не является прямым экземпляром класса POLYGON).

[x]. Если рассматривать операции, применимые к каждому типу, то сказать, что B есть A, означает, что каждая операция, применимая к A применима также и к экземплярам B. (Однако при переопределении B может создать свою собственную реализацию, которая для экземпляров B заменит реализацию, предоставленную A.)

Используя это отношение можно описывать схемы отношения "является", представляющие многие варианты типов, например, все варианты класса FIGURE. Каждая новая версия таких подпрограмм как rotate и display определяется в классе, задающем соответствующий вариант типа. В случае таблиц, например, каждый класс на графе обеспечивает свою собственную реализацию операций search, insert, delete, разумеется, за исключением тех случаев, когда для него подходит реализация родителя.

Предостережение об использовании отношения "является" ("is a"). Начинающие - но я полагаю, ни один из читателей, добравшийся до этого места даже с минимумом внимания, - иногда путают наследование с отношением "экземпляр - образец", считая класс SAN_FRANCISCO наследником класса CITY. Это, как правило, ошибка: CITY - это класс, у которого может быть экземпляр, представляющий Сан Франциско. Чтобы избежать таких ошибок, достаточно помнить, что термин "является" означает не "x является одним из A" (например, "Сан Франциско является городом (CITY)), т.е. отношением между экземпляром и категорией, а выражает "всякий B является A" (например, "всякий ГОРОД является ГЕОГРАФИЧЕСКОЙ_ЕДИНИЦЕЙ"), т.е. отношение между двумя категориями, в программировании - двумя классами. Некоторые авторы предпочитают называть это отношение "является разновидностью" или "может действовать как" [Gore 1996]. Отчасти это дело вкуса (и частично этот предмет будет обсуждаться в лекции о методологии наследования), но поскольку мы уже знаем, как избежать тривиальной ошибки, то будем и далее использовать наиболее распространенное название "является", не забывая при этом, что оно относится к отношению между категориями.

Наследование и децентрализация

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

type FIGURE =

record

"Общие поля"

case figtype: (polygon, rectangle, triangle, circle,...) of

polygon: (vertices: LIST_OF_POINTS; count: INTEGER);

rectangle: (side1, side2: REAL;...);

...

end

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

case f.figure_type of

polygon: ...

circle: ...

...

end

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

Ne sutor ultra crepidam, (для сапожника ничего сверх сандалий) - это принцип разработки ПО: процедуре поворота не требуется знать полный список типов фигур. Ей должно хватать информации необходимой для выполнения своей работы: поворота некоторых видов фигур.

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

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

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

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

present := has (x, t)

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

present := t.has (x)

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

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

Парадокс расширения-специализации

Наследование иногда рассматривается как расширение, а иногда как специализация. Хотя эти два толкования как будто противоречат друг другу, оба они истинны - но с разных точек зрения.

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

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

>Здесь мы говорим о реализуемых компонентах, а не о предлагаемых (клиентам) службах, потому что при соединении скрытия информации с наследованием, как мы увидим, B может скрыть от клиентов некоторые из компонентов, в то время как A их экспортировал своим клиентам.

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

1 ... 137 138 139 140 141 142 143 144 145 ... 188
На этой странице вы можете бесплатно читать книгу Основы объектно-ориентированного программирования - Бертран Мейер бесплатно.
Похожие на Основы объектно-ориентированного программирования - Бертран Мейер книги

Оставить комментарий

Рейтинговые книги