Бертран Мейер - Основы объектно-ориентированного программирования
- Название:Основы объектно-ориентированного программирования
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Бертран Мейер - Основы объектно-ориентированного программирования краткое содержание
Фундаментальный учебник по основам объектно-ориентированного программирования и инженерии программ. В книге подробно излагаются основные понятия объектной технологии – классы, объекты, управление памятью, типизация, наследование, универсализация. Большое внимание уделяется проектированию по контракту и обработке исключений, как механизмам, обеспечивающим корректность и устойчивость программных систем.
В книге Бертрана Мейера рассматриваются основы объектно-ориентированного программирования. Изложение начинается с рассмотрения критериев качества программных систем и обоснования того, как объектная технология разработки может обеспечить требуемое качество. Основные понятия объектной технологии и соответствующая нотация появляются как результат тщательного анализа и обсуждений. Подробно рассматривается понятие класса - центральное понятие объектной технологии. Рассматривается абстрактный тип данных, лежащий в основе класса, совмещение классом роли типа данных и модуля и другие аспекты построения класса. Столь же подробно рассматриваются объекты и проблемы управления памятью. Большая часть книги уделена отношениям между классами – наследованию, универсализации и их роли в построении программных систем. Важную часть книги составляет введение понятия контракта, описание технологии проектирования по контракту, как механизма, обеспечивающего корректность создаваемых программ. Не обойдены вниманием и другие важные темы объектного программирования – скрытие информации, статическая типизация, динамическое связывание и обработка исключений. Глубина охвата рассматриваемых тем делает книгу Бертрана Мейера незаменимой для понимания основ объектного программирования.
Основы объектно-ориентированного программирования - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Полиморфные структуры данных
Рассмотрим массив многоугольников:
poly_arr: ARRAY [POLYGON]
Когда некоторое значение x присваивается элементу этого массива, как в вызове
poly_arr.put (x, some_index)
(для некоторого допустимого значения индекса some_index ), то спецификация класса ARRAY указывает, что тип присваиваемого значения должен быть согласован с типом фактического родового параметра:
class ARRAY [G] creation
...
feature - Изменение элемента
put (v: G; i: INTEGER) is
-- Присвоить v элементу с индексом i
...
end
Так как тип формального аргумента v , соответствующего x , в классе определен как G , а фактический родовой параметр, соответствующий G в вызове poly_arr , - это POLYGON , то тип x должен быть согласован с ним. Как мы видели, для этого x не обязан иметь тип POLYGON , подойдет любой потомок типа POLYGON .
Поэтому, если границы массива равны 1 и 4 , то можно объявить некоторые сущности:
p: POLYGON; r: RECTANGLE; s: SQUARE; t: TRIANGLE
и, создав соответствующие объекты, можно выполнить операции
poly_arr.put (p, 1)
poly_arr.put (r, 2)
poly_arr.put (s, 3)
poly_arr.put (t, 4)
которые присвоят элементам массива ссылки на объекты различных типов.
Рис. 14.4. Полиморфный массив
На этом рисунке графические объекты представлены соответствующими геометрическими фигурами, а не обычными диаграммами объектов с набором их полей. |
Такие структуры данных, содержащие объекты разных типов, имеющих общего предка, называются полиморфными структурами данных. Далее будут рассмотрены многочисленные примеры таких структур. Массивы - это только одна из возможностей, полиморфными могут быть любые структуры контейнеров: списки, стеки и т.п.
Полиморфные структуры данных реализуют цель, сформулированную в начале лекции: объединение порождения и наследования для достижения максимальной гибкости и надежности. Имеет смысл напомнить рис. 10.1, иллюстрирующий эту мысль:
Рис. 14.5. Измерения обобщения
Типы, которые на рис. 10.1неформально назывались SET_OF_BOOKS и т. п., заменены типами, выведенными из родового универсального типа, - SET [BOOK] .
Такая комбинация универсальности и наследования является весьма сильным средством. Оно позволяет описывать структуру объектов с нужной степенью общности. Например,
LIST [RECTANGLE] : может содержать квадраты, но не треугольники.
LIST [POLYGON] : может содержать квадраты, прямоугольники, треугольники, но не круги.
LIST [FIGURE] : может содержать экземпляры любого типа из иерархии FIGURE , но не книги или банковские счета.
LIST [ANY] : может содержать объекты любого типа.
В последнем случае использован класс ANY , который условимся считать предком любого класса (он будет подробнее рассмотрен далее).
Варьируя место класса, выбираемого в качестве фактического родового параметра, в иерархии, можно точно установить границы типов объектов, допустимых в определяемом контейнере.
Типизация при наследовании
Замечательная гибкость, обеспечиваемая наследованием, не связана с потерей надежности, поскольку используется статическая проверка типов, гарантирующая во время компиляции отсутствие некорректных комбинаций типов во время выполнения.
Согласованность типов
Наследование согласовано с системой типов. Основные правила легко объяснить на приведенном выше примере. Предположим, что имеются следующие объявления:
p: POLYGON
r: RECTANGLE
Выделим в приведенной выше иерархии нужный фрагмент ( рис. 14.6).
Тогда законны следующие выражения:
[x]. p.perimeter : никаких проблем, поскольку perimeter определен для многоугольников;
[x]. p.vertices , p.translate (...) , p.rotate (...) с корректными аргументами;
[x]. r.diagonal , r.side1 , r.side2 : эти три компонента объявлены на уровне RECTANGLE или QUADRANGLE ;
[x]. r.vertices , r.translate (...) , r.rotate (...) : эти компоненты объявлены на уровне POLYGON или еще выше и поэтому применимы к прямоугольникам, наследующим все компоненты многоугольников;
[x]. r.perimeter : то же, что и в предыдущем случае. Но у вызываемой здесь функции имеется новое определение в классе RECTANGLE , так что она отличается от функции с тем же именем из класса POLYGON .
Рис. 14.6. Фрагмент иерархии геометрических фигур
А следующие вызовы компонентов незаконны, так как эти компоненты недоступны на уровне многоугольника:
p.side1
p.side2
p.diagonal
Это рассмотрение основано на первом фундаментальном правиле типизации:
Правило Вызова Компонентов
Если тип сущности x основан на классе С , то в вызове компонента x.f сам компонент f должен быть определен в одном из предков С .
Напомним, что класс С является собственным предком. Фраза "тип сущности x основан на классе С " напоминает, что для классов, порожденных из родовых, тип может включать не только имя класса: LINKED_LIST [INTEGER] . Но базовый класс для типа - это LINKED_LIST , так что родовой параметр никак не участвует в нашем правиле.
Как и все другие правила корректности, рассматриваемые в этой книге, правило Вызова Компонентов является статическим, - его можно проверять на основе текста системы, а не по ходу ее выполнения. Компилятор (который, как правило, выполняет такую проверку) будет отвергать классы, содержащие некорректные вызовы компонентов. Если успешно реализовать проверку правил типизации, то не возникнет риск того, что скомпилированная система когда-либо во время выполнения применит некоторый компонент к объекту неподходящего типа.
Статическая типизация - это один из главных ресурсов ОО-технологии для достижения объявленной в 1-ой лекции цели - надежности ПО.
Уже отмечалось, что не все подходы к построению ОО-ПО имеют статическую типизацию. Наиболее известным представителем языков с динамической типизацией является Smalltalk, в котором не действует статическое правило вызова, но допускается, чтобы вычисление аварийно завершалось в случае возникновения ошибки: "сообщение не понятно". В лекции, посвященной типизации, будет приведено сравнение разных подходов. |
Пределы полиморфизма
Интервал:
Закладка: