Одно из важнейших достоинств объектно-ориентированного подхода состоит в
возможности комбинирования этих средств. В результате получается богатый набор
технических приемов совместного и многократного использования кода.
Чистый полиморфизм имеет место, когда одна и та же функция применяется к аргументам
различных типов. В случае чистого полиморфизма есть одна функция (тело кода) и
несколько ее интерпретаций. Другая крайность наблюдается, когда имеется множество
различных функций (то есть тел кода) с одним именем. Такая ситуация называется
перегрузкой или полиморфизмом ad hoc. Между этими двумя полюсами лежат
переопределяемые и отложенные методы
1
.
14.3. Полиморфные переменные
За исключением случаев перегрузки полиморфизм в объектно-ориентированных языках
программирования возможен только за счет существования полиморфных переменных.
Полиморфная переменная многолика: она содержит значения, относящиеся к различным
типам данных. Полиморфные переменные реализуют принцип подстановки. Другими
словами, хотя для такой переменной имеется ожидаемый тип данных, фактический тип
может быть подтипом ожидаемого типа.
В языках с динамическим связыванием (Smalltalk, Objective-C) все переменные являются
потенциально полиморфными (любая переменная может содержать значение любого
типа). В этих языках от типа требуется только некий набор ожидаемых действий.
Например, массив — это то, что по индексу поставляет значение. Иными словами,
пользователь может определить свой собственный тип данных (скажем, разреженный
массив), и если операции индексирования определены с теми же именами, то новый тип
данных может использоваться в уже существующем алгоритме.
В языках со статическими типами данных (таких, как C++, Java, Object Pascal и Objective-
C при использовании статических описаний) ситуация немного сложнее. Мы отмечали,
что эти языки рассматривают создание подклассов как порождение подтипов данных.
Полиморфизм существует в этих языках благодаря различию между декларированным
(статическим) классом переменной и фактическим (динамическим) классом значения,
которое содержится в переменной. Как мы отметили в главе 10, это достигается через
отношение «быть подклассом». Переменная может содержать значение объявленного типа
или любого его подтипа.
В языках Object Pascal и Java это справедливо для всех переменных, описанных с типом
данных object. В C++ и Objective-C с использованием статических описаний полиморфные
переменные существуют только как указатели и ссылки. Опять же, как уже было отмечено
в главе 10, когда указатели не используются, динамический класс переменной всегда
приводится к ее статическому классу.
1
Опять-таки отметим, что согласие в среде сообщества программистов относительно используемой
терминологии весьма невелико. Например, в работах [Horovitz 1984], [Marcotty 1987], [MacLennan 1987] и
[Pinson 1988] термин полиморфизм определяется так, что он приблизительно соответствует понятию,
называемому в данной книге перегрузкой. В работах [Sethi 1989] и [Meyer 1988a], а также в среде людей,
занимающихся функциональным программированием [Wikstrom 1987], [Milner 1990], этот термин
резервируется для обозначения того, что здесь называется чистым полиморфизмом. Другие же авторы
используют этот термин для обозначения одного-двух или всех механизмов полиморфизма,
рассматриваемых в данной главе. Два законченных, но запугивающих избытком технических подробностей
анализа могут быть найдены в работах [Cardelli 1985] и [Danforth 1988].
PDF created with pdfFactory Pro trial version www.pdffactory.com