Чтение онлайн

на главную - закладки

Жанры

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

Мейер Бертран

Шрифт:

has_hash (t, x)

has_linked (t, x)

Но является ли таки достоинством возможность избежать использования различных имен? Наверное нет. Основным правилом создания ПО, объектно оно или нет, является принцип честности (non-deception): различия в семантике должны отражаться в различиях текстов программ. Это позволяет существенно улучшить понятность ПО и минимизировать опасность возникновения ошибок. Если подпрограммы has являются различными, то использование для них одинакового имени может вводить в заблуждение - при чтении текста программы возникает предположение,

что это одинаковые подпрограммы. Лучше предложить клиенту немного более многословный текст (как в случае введенных выше индивидуальных имен) и устранить какую-либо опасность путаницы.

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

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

p1 := new_point (u, v)

Точку можно задать: декартовыми координатами x и y; или полярными координатами r и q (расстоянием от начала координат и углом, отсчитываемым от горизонтальной оси). Но если перегрузить функцию new_point, то возникнет затруднение, связанное с тем, что оба варианта имеют одинаковую сигнатуру:

new_point (p, q: REAL): POINT

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

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

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

Описанную форму перегрузки подпрограмм можно назвать синтаксической перегрузкой. В ОО-подходе будет предложена намного более интересная методика, динамическое связывание, отвечающая целям Независимости Представлений. Динамическое связывание можно назвать семантической перегрузкой. При использовании этой методики и соответствующим образом подобранном синтаксисе можно записать некоторый эквивалент has (t, x) как запрос на выполнение.

Смысл такого запроса примерно таков:

Дорогой Компьютер (Hardware-Software Machine):

Разберитесь, пожалуйста, что такое t; я знаю, что это должна быть таблица, но не знаю, какую реализацию этой таблицы выбрал ее создатель - и, откровенно говоря, лучше, если я останусь в неведении об этом. Как-никак, я занимаюсь не организацией ведения таблиц, а банковскими инвестициями [или компиляцией, или автоматизированным проектированием и т.д.]. Начальник над таблицами здесь кто-то другой. Так что разберитесь в этом сами и, когда получите ответ, поищите подходящий алгоритм для 'has', соответствующий этому конкретному виду таблицы.

Затем используйте найденный алгоритм, чтобы установить, содержится ли 'x' в 't', и сообщите мне результат. Я с нетерпением ожидаю вашего ответа.

С сожалением сообщаю вам что, кроме информации о том, что 't' это некоторого рода таблица, а 'x' это ее возможный элемент, вы не получите от меня больше никакой помощи.

Примите мои дружеские пожелания,

Искренне Ваш разработчик приложений.

В отличие от синтаксической перегрузки, такая семантическая перегрузка является прямым ответом на требование Независимости Представлений. Все еще остается подозрение о нарушении принципа честности (non-deception), и ответом будет использование утверждений (assertions), задающих общую семантику подпрограммы, имеющей много различных вариантов (например, общие свойства, характеризующие has при всевозможных реализациях таблицы).

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

Универсальность (genericity)

Универсальность - это механизм определения параметризованных шаблонов модулей (module patterns), параметры которых представляют собой типы. Это средство является прямым ответом на требование Изменчивости Типов. Оно устраняет необходимость использования многих модулей, таких как:

INTEGER_TABLE_HANDLING

ELECTRON_TABLE_HANDLING

ACCOUNT_TABLE_HANDLING

Вместо этого разрешается написать единственный шаблон модуля в виде:

TABLE_HANDLING [G]

Имя G, представляющее произвольный тип, и называется формальным родовым параметром (formal generic parameter). (Позже мы можем встретиться с необходимостью иметь два или более родовых параметров, но сейчас ограничимся одним.)

Такой параметризованный шаблон называется универсальным модулем (generic module), хотя это еще не настоящий модуль, а лишь общая схема - шаблон многих возможных модулей. Для получения фактического модуля из шаблона, следует задать некоторый тип, называемый фактическим родовым параметром. Модули, получаемые из шаблона заменой формального параметра G на фактический, записываются, например, в виде:

TABLE_HANDLING [INTEGER]

TABLE_HANDLING [ELECTRON]

TABLE_HANDLING [ACCOUNT]

Типы INTEGER, ELECTRON и ACCOUNT использованы, соответственно, в качестве фактических родовых параметров. Такой процесс получения фактического модуля из универсального модуля (шаблона модуля) называется родовым порождением (generic derivation), а сам модуль будет называться "универсально порожденным" (generically derived.).

Поделиться:
Популярные книги

Вернуть Боярство

Мамаев Максим
1. Пепел
Фантастика:
фэнтези
попаданцы
5.40
рейтинг книги
Вернуть Боярство

Кровь на клинке

Трофимов Ерофей
3. Шатун
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Кровь на клинке

Измена. Свадьба дракона

Белова Екатерина
Любовные романы:
любовно-фантастические романы
эро литература
5.00
рейтинг книги
Измена. Свадьба дракона

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Семья

Опсокополос Алексис
10. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Семья

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец

Тринадцатый V

NikL
5. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый V

Скандальный развод, или Хозяйка владений "Драконье сердце"

Милославская Анастасия
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Скандальный развод, или Хозяйка владений Драконье сердце

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Прорвемся, опера! Книга 2

Киров Никита
2. Опер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прорвемся, опера! Книга 2

Корсар

Русич Антон
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
6.29
рейтинг книги
Корсар

Беглый

Шимохин Дмитрий
2. Подкидыш [Шимохин]
Приключения:
прочие приключения
5.00
рейтинг книги
Беглый

Неудержимый. Книга XXVI

Боярский Андрей
26. Неудержимый
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXVI

Убивать чтобы жить 4

Бор Жорж
4. УЧЖ
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 4