присвоенного переменной при ее описании. Термин динамический тип характеризует тип
фактического значения. Тот факт, что динамический и статический типы переменной не
обязаны совпадать, является одним из главнейших достоинств объектно-
ориентированного программирования. Переменная, для которой динамический тип не
совпадает (точнее, может не совпадать) со статическим, называется полиморфной.
Еще два термина имеют отношение к обсуждаемому вопросу. Понятие подкласс уже было
введено в главе 7. Благодаря подклассам новые компоненты программ разрабатываются
на основе уже существующих. Понятие подтипа является более абстрактным. Подтип
определяется в терминах поведения, а не структуры. Мы говорим, что тип В есть подтип
типа А, если мы можем в любой ситуации подставить экземпляр класса В вместо
экземпляра класса А без каких-либо видимых изменений в поведении.
Отметим, что понятие подтипа соответствует нашему идеализированному принципу
подстановки, введенному в главе 9. Однако, абстрактно рассуждая, не существует никаких
видимых причин для того, чтобы понятия подкласса и подтипа имели какую-то
взаимосвязь. Действительно, в языках программирования с динамическими типами
данных вроде Smalltalk они и не связаны. Два класса могут иметь общее поведение —
например, по отношению к одному и тому же набору сообщений, — но без общей
реализации или единого предка (за исключением класса всех объектов Object). Если их
реакции на общие сообщения в достаточной степени аналогичны, то один класс может
быть с легкостью подставлен вместо другого. Представьте себе класс разреженных
массивов, который поддерживает операции класса массивов Array. Тогда в любой
алгоритм, предназначенный для работы с массивами, можно подставить разреженный
массив.
Большинство объектно-ориентированных языков программирования со строгим
контролем типов данных (такие, как Object Pascal и C++) делают размытым различие
между подтипами и подклассами в двух отношениях. Во-первых, они разрешают
переменным принимать значения другого типа, только когда динамический тип значения
является подклассом статического типа. Во-вторых, они предполагают, что фактически
все подклассы являются подтипами. Это предположение не всегда справедливо.
Поскольку подклассы могут переопределять методы родителей на произвольное новое
поведение, то в общем случае не существует никаких гарантий того, что подкласс будет
также и подтипом.
10.1. Связывание методов и сообщения
В следующем разделе мы обсудим, как выглядит различие между подклассами и
подтипами в обсуждаемых нами языках программирования. Прежде всего, однако, мы
должны затронуть две проблемы. Первая из них связана с вопросом о способе связывания.
Должны ли мы связывать сообщение и метод, основываясь на статическом типе
переменной, или следует принять во внимание ее динамический тип? Второй проблемой
является вопрос обращения полиморфизма — можно ли присвоить значение переменной,
основываясь на ее динамическом, а не на статическом типе? Третий, тесно связанный с
данной темой вопрос — а именно о точном значении переопределения методов, —
достаточно сложен, поэтому мы отложим его обсуждение до следующей главы.
10.1.1. Связывание методов
Существование полиморфной переменной естественным образом
PDF created with pdfFactory Pro trial version www.pdffactory.com