Введение в системы БД (542480), страница 189
Текст из файла (страница 189)
Например, тип ЕЬЫРЯЕ является супертипом для типа ЕЬЫРЯЕ. 3. Если А — супертип типа В и типы А и В различны, то тип А — действительный (ргорег) супертип типа В. Например, тип РОЬХ60Н вЂ” это действительный супертип типа ЯООАНЕ. Безусловно, аналогичные замечания справедливы и для подтипов. 4. Подтип подтипа сам является подтипом. Например, тип ЯООАНŠ— это подтип типа РОЬХ60Н. 5. Каждый тип является подтипом для самого себя.
Например, тип ЕЬЫРЯЕ является подтипом типа ЕЬЫРЯЕ. б. Если  — подтип типа А и типы В и А различны, то тип  — действительный подтип типа А. Например, тип ЯООАНŠ— это действительный подтип типа РОЬХООН. Кроме того, дадим дополнительные определения. 7. Если А — супертип типа В и не существует типа С, который был бы действительным подтипом типа А и действительным супертипом типа В, то А — непосредственный супертип типа В, а  — непосредственный подтип типа А.
Например, тип НЕСТАНОЬŠ— непосредственный супертип типа ЯООАНЕ, а тип ЯООАНŠ— непосредственный подтип типа НЕСТАНОЬЕ. (Отметим, что в синтаксисе языка Та!от!а! Р ключевое слово ЯОВТХРЕ ОР означает именно "непосредственнын подтип".) 8. Корневой тип — это тип, не имеюший ни одного действительного супертипа. Например, тип РЬАНЕ Р160НŠ— это корневой тни. Замечание.
Это не означает, что может существовать только один корневой тип. Однако, если имеются два или более корневых типа, всегда можно ввести тот или иной вариант "системного" типа, который будет непосредственным супертипом для всех остальных. Поэтому, не теряя обшности, можно считать, что корневой тип всегда один. 9. Листовой тип — это тип, не имеющий ни одного собственного подтипа, Например, тип С1НСЬŠ— это листовой тип. Глава 19. Наследование типов Замечание.
Данное определение несколько упрощено, хотя и вполне удовлетворительно для наших целей (однако в случае множественного наследования его потребуется дополнить 13.3)). !О. Каждый действительный подтип имеет только один действительный супертип. Замечание. Это явное следствие из сделанного выше допущения о том, что здесь будет рассматриваться только одиночное наследование. Как уже отмечалось, все возможные последствия отмены данного допущения (т.е. множественное наследование) подробно описаны в !3.3).
11. Если в иерархии существует по крайней мере один тип и не существует циклов (т.е. последовательностей вида Т1, Т2, ТЗ, ..., Тп, таких, что тип Т1 — непосредственный подтип типа Т2, тип Т2 — непосредственный подтип типа Т3, ... и Тп — непосредственный подтип типа Т1), то по крайней мере один тип должен быть корневым. Замечание. На самом деле никаких циклов быть просто не маэкет (почему?). Предположение о несвязности Для упрощения обсуждения примем еще одно допущение. Если Т1 и Т2 — различные корневые типы или различные непосредственные подтипы некоторого супертипа (откуда, в частности, следует, что ни один из них не является подтипом другого), то будем считать, что эти типы являются несвязанными, т.е, не существует значений, принадлежащих обоим типам, Т1 и Т2.
Например, не существует значений, относящихся одновременно к типу ЕВРЕЕ и к типу РОЫООЕ. Прямыми следствиями этого предположения являются приведенные ниже утверждения. 12. Различные иерархии типов являются несвязанными. !3. Различные листовые типы являются несвязанными. !4. Каждое значение относится ровно к одному конкретному типу. Например, некоторое значение может быть именно эллипсом, а не окружностью, т.е. конкретный тип этого значения — ЕВРЕЕ (в реальном мире некоторые эллипсы не являются окружностями). В действительности вместо того, чтобы сказать, что конкретный тип некоторого значения ч есть Т, будет лучше сказать, что множество типов, к которым относится значение ч, — это множество всех супертипов типа Т (множество, которое, конечно, включает и сам тип Т).
Одно из преимуществ принятия допущения о несвязности заключается в том, что исключается двусмысленность, которая может иметь место в противном случае. Предположим, что некоторое значение ч относится к двум типам, Т1 и Т2, причем ни один из них не является подтипом другого. Далее предположим, что оператор Ор был определен для типа Т1, а другой, с тем же именем Ор, — для типа Т2г. Тогда применение оператора Ор с аргументом ч могло бы привести к неоднозначности.
г Другими словами, оператор Ор — эта полиморфный оператор. Кроме того, палимаргризч в данном случае маг бы быть либо перегружаемым, либо включаемым. В разделе 19.3 этот вопрос будет рассмотрен подробнее. Часть !г. дополнительные аспекты Замечание. Предположение о несвязности имеет смысл, поскольку мы ограничиваемся рассмотрением лишь одиночного наследования, а для множественного наследования это ограничение должно быть снято. Детальное обсуждение данного вопроса можно найти все в той же работе (3.3]. Физическое представление Хотя нас интересует, прежде всего, модель наследования, а не ее физическая реализация, все же имеются вопросы, в которых необходимо разобраться подробнее, чтобы яснее представлять концепцию наследования в целом. Вот один из таких вопросов.
15. Из того, что тип В является подтипом типа А, не следует, что реальное (скрытое) представление значений типа В то же самое, что и значений типа Аз. Например, эллипсы реально могут быть представлены их центрами и полуосями, в то время как окружности — центрами и радиусами (хотя в общем случае не существует каких- либо требований в отношении того, чтобы реальные представления были точно такими, как вышеназванные). Для изучения нескольких послелуюших разделов этот вопрос также будет важен, 19.3. Полиморфизм и заменимость В этом разделе рассматриваются два ключевых понятия — полиморфизм и за.иенимасть, которзяе вместе составляют основу для возможности повторного использования кода, упоминавшейся в разлеле 19.!. Сразу же отметим, что оба понятия в действительности представляют собой различные взгляды на одно и то же явление.
Тем не менее рассмотрим сначала понятие полиморфизма. Полиморфизм Из самого понятия наследования следует, что если Т' — это подтип типа Т, то все операторы, которые применимы к значениям типа Т, применимы и к значениям типа Т'. Например, если оператор АКЕА(е) является допустимым, где е — некоторый эллипс, то оператор АКЕА(с), где с — некоторая окружность, также лолжен быть допустимым. Заметим, что необходимо соблюдать аккуратность в отношении отличия парачзепзров в смысле их типов, объявленных в определении оператора, и соответствующих аргулзентав с действительными (конкретными) типами, использованных при вызове этого оператора.
Например, оператор АКЕА определен с параметром, объявленным относяшимся к типу ЕЬЬТРВЕ (см. раздел 19.2), а действительный (конкретный) тип аргумента в обрашении к оператору АКЕА(с) — имеющим тип СТКСЬЕ. Действительна, иет никакой логической неабтадииасти даже в там, чтобы все значения одного и того же птпа имели одно и та же реальное представление. Например, одни тачки магут быль представлены в декартавай систелзе координат, а другие — в полярной системе каардинат; одни значения температуры лзагупз быть представлены в градусах па Нельсию, а другие — а градусах па Фаренгеипзут одни целые чисяа люгут быпт представлены как десятичные, а другие — как двоичные и т.д. /Канечна, систелче далжна быть извеспчла, как преабразавывапи реачьные предспчавления ва всех таких случаях, чтобы можно было правильно выпалнять аперацни присваения, сравиечтя и т д1 733 Глава )у.
Наследование типов Напомним, что эллипсы и окружности (по крайней мере, как мы их определили в разделе 19.2) имеют различные представления. ТУРЕ ЕЬЬ1РБЕ РОЯБВЕР ( А ЬЕНОТН, В ЬЕНОТН, СТВ Р01НТ )... ТУРЕ С1ВСЬЕ РОЯЯВЕР ( В ЬЕНОТН, СТВ Р01НТ )... Поэтому, возможно, могут существовать, хотя это и скрыто от пользователя, две различные версии оператора АВЕА: одна позволяет использовать представление ЕЬЫРБЕ, а другая — представление С1ВСЬЕ. Повторим, это возможно, но в этом может и не быть неабхадимасгни. Например, кол оператора для эллипса может выглядеть таким образом. ОРЕВАТОВ АВЕА ( Е ЕЬЫРЯЕ ) ВЕТОВМЯ ( АВЕА ВЕТОВН ( 3.14159 * ТНЕ А ( Е ) * ТНЕ В ( Е ) ) ЕНО ОРЕВАТОВ 1 (Площадь эллипса равна паЬ.) Этот код, очевидно, дает правильный результат и в том случае, если вызывается для вычисления плошади окружности, а не эллипса.
Операторы ТНЕ А и ТНЕ В возвращают радиус г. Однако программист, ответственный за определение типа С1ВСЬЕ, может по разным соображениям предпочесть реализацию отлельной версии оператора АВВА, которая предназначена конкретно для окружностей и в которой вызывается оператор ТНЕ В вместо операторов ТНЕ А и ТНЕ В. Занечание. На самом деле может быть желательной реализация двух версий оператора, даже если возможные представления одни и те же, в частности по соображениям эффективности.
Рассмотрим, например, многоугольники и прямоугольники. Алгоритм вычисления площади многоугольников годится, конечно, и для прямоугольников, но всетаки для прямоугольников более эффективно вычислять плошадь как произведение их ширины и высоты. Однако отметим, что код для реализации вычисления площади фигуры типа ЕЬЫРЯЕ не будет пригодным лля окружностей, если он написан в терминах реального представления типа ЕЬЫРБЕ вместо возможного, поскольку реальные представления лля типов ЕЬЫРЯЕ и С1ВСЬЕ отличаются. И вообще, практика реализации операторов в терминах реальных представлений — это не лучший подход.
Кодируйте надежно! В случае, если код оператора АВЕА, используемый для типа ЕЬЫРБЕ, не нужно переписывать заново для типа С1ВСЬЕ, можно говорить о повторном использовании кода (т.е. кода, реализующего оператор АВВА). Заиечание. В следующем подразделе речь пойдет о более важном виде повторного использования.