Категории
Самые читаемые
Лучшие книги » Компьютеры и Интернет » Прочая околокомпьтерная литература » Основы объектно-ориентированного программирования - Бертран Мейер

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

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 126 127 128 129 130 131 132 133 134 ... 188
Перейти на страницу:

Ключевые концепции

[x]. Внешние программы доступны через хорошо определенный интерфейс.

[x]. Объектная технология может служить в качестве механизма упаковки наследуемого ПО.

[x]. Подпрограммы не могут модифицировать свои аргументы, хотя они могут изменять объекты, связанные с этими аргументами.

[x]. Нотация включает небольшой набор инструкций: присваивания, выбора, цикла, вызова, отладки и проверки.

[x]. Выражения следуют общепринятому стилю. Current - выражение, обозначающее текущий экземпляр. Не будучи сущностью, Current не может быть целью присваивания.

[x]. Нестрогие булевы операторы эквивалентны стандартным булевым оператором, когда определены оба операнда, но могут быть определенными в случаях, когда стандартные операторы не определены.

[x]. Строки, ввод и вывод определяются простыми библиотечными классами.

[x]. Регистр незначим в идентификаторах, хотя правила стиля включают рекомендуемые соглашения по записи имен.

Упражнения

У13.1 Внешние классы

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

У13.2 Избегая нестрогих операторов

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

Лекция 14. Введение в наследование

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

Многоугольники и прямоугольники

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

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

При обеспечении расширяемости (extendibility) преимущество описанной выше системы типов состоит в гарантированной совместности во время компиляции, но она запрещает многие вполне законные комбинации элементов. Например, нельзя объявить массив, содержащий геометрические объекты различных совместных типов, таких как POINT (ТОЧКА) и SEGMENT(ОТРЕЗОК).

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

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

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

Многоугольники

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

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

indexing

description: "Многоугольники с произвольным числом вершин"

class POLYGON creation

...

feature -- Доступ

count: INTEGER

-- Число вершин

perimeter: REAL is

-- Длина периметра

do ... end

feature -- Преобразование

display is

-- Вывод многоугольника на экран.

do ... end

rotate (center: POINT; angle: REAL) is

-- Поворот на угол angle вокруг точки center.

do

... См. далее ...

end

translate (a, b: REAL) is

-- Сдвиг на a по горизонтали, на b по вертикали.

do ... end

... Объявления других компонентов ...

feature {NONE} -- Реализация

vertices: LINKED_LIST [POINT]

-- Список вершин многоугольника

invariant

same_count_as_implementation: count = vertices.count

at_least_three: count >= 3

-- У многоугольника не менее трех вершин (см. упражнение У14.2)

end

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

Приведем реализацию типичной процедуры rotate. Эта процедура осуществляет поворот на заданный угол вокруг заданного центра поворота. Для поворота многоугольника достаточно повернуть по очереди каждую его вершину.

rotate (center: POINT; angle: REAL) is

-- Поворот вокруг точки center на угол angle.

do

from

vertices.start

until

vertices.after

loop

vertices.item.rotate (center, angle)

vertices.forth

end

end

Чтобы понять эту процедуру заметим, что компонент item из LINKED_LIST возвращает значение текущего элемента списка. Поскольку vertices имеют тип LINKED_LIST [POINT], то vertices.item обозначает точку, к которой можно применить процедуру поворота rotate, определенную для класса POINT в предыдущей лекции. Это вполне корректно и достаточно общепринято - давать одно и то же имя (в данном случае rotate), компонентам разных классов, поскольку результирующее множество каждого из них имеет свой явно определенный тип. (Это ОО-форма перегрузки.)

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

perimeter: REAL is

-- Сумма длин ребер

local

this, previous: POINT

do

from

vertices.start; this := vertices.item

check not vertices.after end -- Следствие условия at_least_three

until

vertices.is_last

loop

previous := this

vertices.forth

this := vertices.item

Result := Result + this.distance (previous)

end

Result := Result + this.distance (vertices.first)

end

В этом цикле просто последовательно складываются расстояния между соседними вершинами. Функция distance была определена в классе POINT. Значение Result, возвращаемое этой функцией, при инициализации получает значение 0. Из класса LINKED_LIST используются следующие компоненты: first дает первый элемент списка, start сдвигает курсор, на этот первый элемент, forth передвигает его на следующий, item выдает значение элемента под курсором, is_last определяет, является ли текущий элемент последним, after узнает, что курсор оказался за последним элементом. Как указано в команде check инвариант at_least_three обеспечивает правильное начало и завершение цикла. Он стартует в состоянии not after, в котором элемент vertices.item определен. Допустимо применение forth один или более раз, что, в конце концов, приведет в состояние, удовлетворяющее условию выхода из цикла is_last.

1 ... 126 127 128 129 130 131 132 133 134 ... 188
Перейти на страницу:
На этой странице вы можете бесплатно скачать Основы объектно-ориентированного программирования - Бертран Мейер торрент бесплатно.
Комментарии
Открыть боковую панель
Комментарии
Сергей
Сергей 24.01.2024 - 17:40
Интересно было, если вчитаться