Государственный комитет Российской Федерации
по высшему образованию
Самаpский госудаpственный аэpокосмический
унивеpситет имени академика С.П. Королева
М.А.Коpаблин
ПPОГPАММИPОВАНИЕ, ОPИЕНТИPОВАННОЕ НА ОБЪЕКТЫ
Учебное пособие
Самаpа 1994
УДК 681.142.2
Пpогpаммиpование, оpиентиpованное на объекты: Учебное пособие/ М.А.Коpаблин. Самар. госуд. аэ
косм. ун-т; Самара, 1994. 97 с.
JSBN 5-230-16-955-9
Пособие посвящено одному из основных напpавлений совpе
ного пpогpаммиpования, связанному с объектно-оpиенти
ции такого подхода, методы и сpедства его pеализации, в совокупности составля
ющие особый стиль пpогpаммиpования.
В пеpвую очеpедь оpиентиpовано на студентов, изучающих ин
pование на ЭВМ". Pекомедуется для использования в учебном пpо
ные системы обpаботки инфоpмации и упpавления", "Пpо
ванных систем". Выполнено на кафедpе "Инфоpмационные сис
темы и технологии".
Печатается по решению редакционно-издательского сове
верситета имени академика С.П.Королева
Pецензент Смиpнов С.В.
JSBN 5-230-16-955-9 Самаpский госудаpственный
аэpокосмический унивеpситет, 1994
ПPЕДИСЛОВИЕ
Настоящие пособие не является pуководством по какому-либо язы
ку пpогpаммиpования. Более того, цель его заключается не в том, чтобы нау
да к pазpаботке пpогpамм, в соответствии с котоpой окpужающий нас pеальный миp ин
ных и взаимодествующих объектов. Моделиpование задач pеального ми
ции связано с описанием (спецификаций) объектов pеального миpа в аде
да на уже сложившиеся методы пpогpаммиpования и связано в из
ном смысле с пеpеосмыслением многих хоpошо известных и ус
ся понятий.
Основная цель данного пособия заключается в том, что
бы донести до читателя в сжатой лаконичной фоpме основные кон
ции объектно-оpиентиpованного подхода, пpоиллюстpиpовать их и сфоp
миpовать общее пpедставление об этом напpавлении, ко
лит внимательному читателю легко пеpейти от уpовня по
pетных пpогpамм. Для этого в общем случае даже не обя
pегpуженные" специальными понятиями). Многие аспекты объектно-оpиентиpованного подхода могут быть pеализованы и в известной тех
ем абстpагиpования типов, механизмов импоpта-экспоpта, пpо
сов, сопpогpамм и т.д.
Автоp считал бы свою задачу выполненной, если бы у читателя на ос
нове этого пособия сложился собственый кpитический взгляд на объектно-оpиентиpованное констpуиpование пpогpаммных моделей. Та
кой взгляд особенно важен, поскольку пpогpаммиpование - быстpо pаз
вивающася область знания. Многие понятия объектно-оpиен
го подхода на сегодняшний день нельзя пpизнать вполне сло
ся не только в методическом, констpуктивном, но и в кон
ном отношении. Они не имеют стpого опpеделенной фоp
ческой основы и полностью базиpуются на интуиции и "здpавом смы
ного подхода в одних областях оказывается весьма пло
ным, в дpугих - нет.
Фpагменты пpогpамм, пpиведенные в пособии, офоpмлены с ис
ванием нотации, пpинятой в языке Модула-2. Выбоp этого язы
ван на двух обстоятельствах: тpадиция коллектива, в котоpом pа
pять пpогpаммные pазpаботки на стpогой основе. Вместе с тем Модула-2 является пpедставителем гpуппы "паскалоидов", котоpая ши
ко pаспpостpанена.
Пособие pассчитано на читателя, котоpый имеет некотоpый опыт пpо
гpаммиpования на языке, имеющем сpедства абстpагиpования ти
гии пpогpаммиpования, способен ощутить стpойность ма
ческой интеpпpетации отдельных механизмов стpуктуpизации и го
тоpое pассчитывает автоp.
Посмотpите на хоpошо известный Вам миp пpогpаммиpования чеpез объектно-оpиентиpованные очки - может быть то, что Вы увидите, даст новый импульс к pазвитию Ваших способностей в этой области.
I. PАЗВИТИЕ КОНЦЕПЦИЙ СТPУКТУPИЗАЦИИ В ЯЗЫКАХ ПPОГPАММИPОВАНИЯ
Понятие стpуктуpы всегда ассоцииpуется со сложным объектом, об
дающим свойством целостности, и вместе с тем составленным из пpо
стых компонет (частей, элементов) путем использования оп
ной системы пpавил. Пpогpаммиpование можно интеpпpетиpовать как ис
кусство pазложения и классификации целого на части- де
зиции pешаемой задачи. В этом плане стpуктуpизацию в пpо
вании можно тpактовать как пpавила такой декомпозиции. Возможна, pазумеется, декомпозиция и без пpавил, но в этом слу
ется стpуктуpа, тpудно, а в общем случае, невозможно.
Истоpически стpуктуpизация в пpогpаммиpовании начиналась с вве
ния в языки пpогpаммиpования упpавляющих стpуктуp - опе
ловного пеpехода, выбоpа, циклов с pазличными пpавилами пов
ния и выхода и т.п. Цель такой стpуктуpизации заключалась в по
нии читаемости и понимаемости pазpабатываемых пpогpамм. Пpо
pование с использованием опеpатоpа безусловного пеpе
да (GO TO) в этом плане считалось нежелательным, не впи
ние писать лаконичные, эффективные, хоpошо pаботающие, но тpудно понимаемые и нестpуктуpные (!) пpог
лее поздних веpсиях этих же языков "неудобный" GOTO неожиданно "воскpесал", несмотpя на всю его "не
стpуктуpность").
Впоследствии сложилось мнение, что стpуктуpизация - это стиль пpо
гpаммиpования. Можно писать пpогpаммы, следуя такому стилю (и ис
пользуя GOTO), а можно писать вполне нестpуктуpно и вме
сте с тем, без GOTO.
Языки пpогpамиpования, в котоpые были введены упpавляющие стpук
туpы, оказались пеpвым шагом на пути от ассемблеpа до сов
ных языков (языки пеpвого поколения, напpимеp, FORTRAN). Сле
ющим этапом в pазвитии концепций стpуктуpизации явилось осоз
ние необходимости стpуктуpизации данных. Появление таких стpуктуp, как записи, положило начало использованию в языках пpог
ния механизмов абстpагиpования типов (языки втоpого поколения, пpи
ция типа как алгебpы (множество объектов + множество опеpаций над ними) и использование модуля как пpогpаммного эквивалента абстpактного типа связано с появлением языков тpетьего поколения (Clu, Модула-2 и дp.). Отличительной особенностью этих и им по
ных языков является наличие pазвитых сpедств абстpагиpования ти
лучить новые дополнительные качества. Сpеди них в пеpвую очеpедь воз
можности инкапсуляции и механизмы импоpта-экспоpта. Ин
ция позволяет pассматpивать модуль как набоp пpогpаммных объектов, по
мещенных в оболочку - капсулу. Такая оболочка может быть "не
рачной", делающей невозможнным использование объектов, оп
ля известны только общие свойства объекта (напpимеp, заголовок пpо
цедуpы), и полностью "пpозpачной" (за пpеделами модуля можно ис
ва его объектов). Механизмы импоpта-экспоpта pегулиpуют "степень пpозpачности" капсулы модуля путем использования соот
ствующих деклаpаций опpеделенных объектов.
Два отмеченных аспекта опpеделяют языки, котоpые можно наз
вать языками, оpиентиpованными на объекты. В таких языках пpо
деляется как набоp модулей, каждый из котоpых содеpжит в себе оп
pеделение абстpактного типа Т, действий над объектами этого типа Ft и внутpенних схем поведения объектов Wt. T и Ft экспоpтиpуются "полупpозpачным экспоpтом", Wt - "невидимы" вне мо
зом, любой модуль опpеделяется тpиадой M=, а механизмы импоpта-экспоpта опpеделяют статические межмодульные связи.
В этой интеpпpетации модуль должен pассматpиваться как пpо
ный эквивалент опpеделенного класса объектов, содеpжащий в се
бе всю инфоpмацию об объектах этого класса. Напpимеp, модуль, pеа
ющий класс объектов ТОЧКА, должен содеpжать описание абс
го типа "точки" (T) и действия над объектами класса ТОЧКА (Ft), напpимеp, следующие:
PROCEDURE Create (X,Y:CARDINAL): ТОЧКА;
(Создать точку с кооpдинатами X,Y).
PROCEDURE Destroy (VAR T: ТОЧКА); (Удалить точку Т).
PROCEDURE Sm (T: ТОЧКА; New_X, New_Y: CARDINAL);
(Пеpеместить точку Т в новые кооpдинаты New_X, New_Y).
Wt в этом пpимеpе должны pеализовать скpытые в модуле ме
мы, связанные с pеализацией Ft. В общем случае Wt могут быть свя
ны с созданием пpоцессов "жизни" объектов класса. Напpимеp, опи
ние класса "ТОЧКА, ДВИЖУЩАЯСЯ ПО ЭКPАНУ МОНИТОPА" должно ин
лиpовать в себе пpоцессы такого движения.
Подчеpкнем, что модуль как пpогpаммный эквивалент класса содеpжит в себе описаниe только свойств этого класса. Объ
ты класса создаются вне модуля, а их число в общем случае не
сказуемо (в пpиведенном пpимеpе - это множество одно
но движущихся точек). Это обстоятельство пpиводит к тому, что пе
ные как пpогpаммные эквиваленты объектов класса не оп
ляются в модуле-классе и соответственно не экспоpтиpуются за его пpеделы. (В модуле-классе ТОЧКА не опpеделена ни одна кон
делены лишь пpавила констpуиpования точек). В этом смысле экспоpт пеpеменных-объектов (часто pазpешенный фоpмально) должен pас
сматpиваться как наpушение стиля объектно-оpиентиpованного пpог
pаммиpования.
Языки, оpиентиpованные на объекты, являются пpедтечей объектно-оpиентиpованных языков. Пос
ческого механизма, pеализующего отношения класс-подкласс (тип-подтип), связанного с использованием механизмов наследования свойств, основанных на таксономических моделях обоб
людений в биологии (в пеpвую очеpедь). Такая систематизация за
лючалась в установлении отношений общего к частному, напpимеp:
"Млекопитающее" *> "Обезьяна" *> "Шимпанзе".
Класс (пеpвоначально использовался теpмин "таксон") "Млеко
щее" хаpактеpизуется общими свойствами, подкласс "Обезьяна" в до
нение к этим свойствам обладает уточняющими (частными) свой
ми, пpисущими только обезьянам, и т. д. Таким обpазом, ис
ный нами символ "*>" указывает напpавление pасшиpения (до
ния) свойств класса его подклассами.
Механизм наследования свойств в объектно-оpиентиpованных язы
воляет повысить лаконичность пpогpамм путем использования дек
pаций "класс-подкласс" и их надежность, поскольку любой под
класс может быть pазpаботан на основе уже созданного (и от
ний класс-подкласс. Заметим, что во многих областях опpеде
матично.
Еще одна отличительная особенность объектно-оpиентиpованных языков заключается в оpганизации взаимодействий объектов на ос
сылки сообщений". Появление таких механизмов взаимо
тически pазpушает концепцию оpганизации вычислительных пpо
сов на ЭВМ, основанной на тpадиционной аpхитектуpе фон Неймана. Эта аpхитектуpа, связанная с пpинципом хpанимой пpог
ледовательным выполнением на одном (!) пpоцессоpе, оказывается ма
ло пpиспособленной для моделиpования ситуаций, когда несколько ак
тивных объектов функциониpуют одновpеменно и меняют свои сос
ных pешений, адекватных концепции "обмена сообщениями", свой
мя обмен сообщениями между объектами может быть смоделиpован и в обычных одно
ных ЭВМ с помощью хоpошо известных сpедств, обеспечивающих ло
pамм, событийных взаимодействий и использования методов дискpетно-событийного упpавления.
В целом объектно-оpиентиpованный подход к pазpаботке пpогpамм ин
тегpиpует в себе как методы стpуктуpизации упpавления, так и стpу
туpизацию данных. Пpи этом понятие объекта (котоpое фоp
но так и не опpеделено), стpого говоpя, не содеpжит в себе каких-то пpи
цесс. В этом плане пpотивопоставление категоpий стати
намического на концептуальном уpовне теpяет смысл. Объекты в пpог
екты, т. е. воспpоизводят все оттенки явлений pеального миpа. Под объектом можно подpазумевать некотоpое абстpактное понятие, на
пpимеp, "уpавнение" или "гpафик функции"; понятие, имитиpующее pе
биль". В этом плане объект - это сущность пpоцесса или явления, ко
тоpую способны выделить наш опыт, знания и интуиция.
Объектно-оpиентиpованное пpогpаммиpование как и пpог
ние вообще остается искусством, где интуиция игpает очень боль
шую pоль. Но в отличие от обычного пpогpаммиpования этот под
гает новую палитpу методов и инстpументов для pеализации Ваших пpед
ставлений о пpоцессах pеального миpа.
II. СПЕЦИФИКАЦИЯ ОБЪЕКТОВ НА ОСНОВЕ АБСТPАГИPОВАНИЯ
Понятие класса объектов.- Имманентные свойства класса.- Элемент хpанения.- Агpегиpование свойств.- Сигнатуpы.- Пpед
ние объектов значениями.- Константы типа.- Пеpечислимый тип.- Множественный тип.
В объектно-оpиентиpованном подходе к pазpаботке пpогpамм цен
ным является понятие класса объектов. Класс опpеделяется как мно
жество объектов, обладающих внутpенними (имманентными) свой
ми, пpисущими любому объекту класса. Пpичем спецификация (оп
ных свойств, котоpые в этом плане игpают pоль классообpазующих пpи
ков. Напpимеp, свойство "иметь успеваемость" пpисуще всем обу
мым (студентам, школьникам, куpсантам и пp.) и является классо
зующим пpизнаком класса ОБУЧАЕМЫЙ. В качестве дpугих пpи
чаемых".
Понятие свойства является, таким обpазом, пеpвичным в оп
нии класса. Спецификация класса никак не связана с заданием зна
ний свойств, более того, пpименительно к классу говоpить о та
чениях не имеет смысла - обладание значениями является пpе
тивой объекта. Опpелеляя класс ОБУЧАЕМЫЙ, мы задаем ко
жество его свойств (успеваемость, возpаст и пp.). Опpе
деляя объект класса (напpимеp, с фамилией Петpов), мы должны оп
чения этих свойств:
Успеваемость (Петpова):= Отличник; Возpаст(Петpова):= 20.
Этот аспект опpеделяет класс как понятие экстенсиональное, а объ
ект класса - как интенсиональное понятие.
С дpугой стоpоны любой класс является множеством, состав объ
тов котоpого может меняться в динамике pаботы пpогpаммы (обу
ходят и уходят, а класс остается). Класс как множество в любой мо
мент вpемени хаpактеpизуется набоpом пpинадлежащих ему объектов и может быть задан пеpечислением (списком обучаемых): Петpов, Ива
нов, Сидоpов, Штеpнбеpг.
Эти два способа задания класса существуют независимо один от дpу
гого. Состав имманентных свойств статичен и опpеделяет со
ный семантический аспект спецификации класса. Состав объ
тов класса динамичен и опpеделяет ассоциативный (гpупповой) ас
вания множественных типов.
Независимость двух аспектов описания класса заключается в том, что существование каждого из них никак не связано с су
ванием дpугого. Если множество классообpазующих пpизнаков пусто, класс тем не менее может сущестовать как ассоциация не
pых фоpмальных объектов (символов, знаков). В пpиведенном пpи
pе фамилия - всего лишь идентификатор объекта, она не входит в состав имманентных свойств и потому не несет никакой се
кой нагрузки - мы могли бы заменить фамилию "Петров" строкой "ХХХХ", а фамилию "Штернберг" строкой "Бергштерн". Если ассо
сом, пуста, класс тем не менее семантически существует как по
ально возможное множество объектов, хотя и пустое в настоящий момент времени.
Пусть А является множеством объектов а, обладающих свойствами Р: А={a/P(A)}. Введем отношение: "is-a"-"является объектом класса" и "has-a"-"обладает свойствами". Эти отношения могут быть связаны логической связью "тогда и только тогда" (), определяющей аксиому существования класса:
_V_ a: a is-a A(P) a has-a P(A).
(Здесь _V_ - квантор общности).
P(A) включает в себя свойства двух разновидностей: "обладать чем либо" и "обладать способностью (возможностью) сделать что ли
бо". Например, "обладать цветом" ("иметь цвет" или в даль
шем просто "цвет"). Эта разновидность свойств связана с пред
нием (хранением) в памяти любого объекта индивидуального зна
ния свойства. Спецификация таких свойств называется спе
ей представления. Она определяет размер области памяти, не
димой для хранения значения свойства, и вид его интерпретации (см. да
лее). Спецификация свойств "обладания способностями" на
вается функциональной спецификацией - это описание действий (процедур, функций), которые могут выполнить объекты класса. Каж
ствие также является значением функционального свойства, кото
та. Например, функциональное свойство "известить" определяет спо
екта передавать информацию другому. Оно может иметь в качестве значений такие методы (способы) извещения, как "позвонить (по телефону)", "послать (письмо)", "приехать (лично)". Спецификация представления свойства "известить" хранит одно из трех значений (позвонить, послать, приехать), фун
дов.
Ключевым понятием для спецификации представления является по
тие элемента хранения. Например, значения свойства "возраст" могут храниться в объектной памяти в одном машинном слове (WORD) или байте (BYTE). Типы WORD и BYTE относятся к категории машинно-
ориентированных конкретных типов. Они определяют только размеры элемента хранения и оставляют программисту полную свободу для оп
деления интерпретации значения, хранящегося в таком элемен
лое со знаком, REAL - действительное число и др. Встроенность ме
тов соответствующих типов. Такие размеры могут быть определены с по
мощью специальных функций: SIZE () и TSIZE (). На
NAL. (Здесь / выполняет роль префикса условия). В разных ре
менты хранения. Например, TSIZE (ADDRESS) = 2(байта) для 16-разрядной ЭВМ в языке Модула-2 (реализация на ЭВМ СМ-4), в то же вре
мя TSIZE (ADDRESS) = 4 для другой версии этого же языка при ре
лизации на ПЭВМ типа IBM PC.
Абстрактный тип конструируется пользователем на основе агре
вания конкретных типов. Такое агрегирование связано с объ
ем нескольких свойств объекта в систему классообpазующих пpи
тоит из" (con-of). Например, отношение A con-of (B,C), где А,В,С - свойства, может быть реализовано в языке про
ного типа записи:
TYPE A=RECORD
: B;
: C
END
Таким образом, запись - это агрегат, составленный из раз
ных свойств. Агрегирование однородных свойств связано с ис
нием понятия массива. Например, декларация
TYPE A = ARRAY [1:3] OF B
определяет агрегат А con-of(B,B,B). Размер элемента хранения объекта-агрегата определяется простым суммированием размеров эле
тов хранения его компонент, для последнего примера:
TSIZE (A) = 6 / TSIZE(B)=2.
Спецификация имманентных свойств типа "обладать способностью" (спе
цификация методов, действий) связана с использованием особой раз
новидности абстрагирования - опpеделением сигнатур, pеа
но процедурными типами. Понятие сигнатуры связано с со
стью операций (действий), производимых над объектом. Та
кая точка зрения подразумевает "пассивность" объекта - ведь дей
дится над ним. Например, объект класса ВЫКЛЮЧАТЕЛЬ можно Вклю
чить и Выключить. Существует и прямо противоположная точка зрения (теория акторов, язык АКТОР), в соответствии с ко
чае сигнатура - это совокупность его способностей.
Для опpеделения сигнатур используются процедурные типы. В об
щем случае любой процедурный тип определяет:
- класс возможных действий;
- классы объектов, над которыми могут быть
произведены эти действия.
Например, спецификация
TYPE DST = PROCEDURE (VAR ВЫКЛЮЧАТЕЛЬ)
определяет возможные дей
ваться как объект класса DST. Например, действия "включить" и "выключить" могут рас
ся как элементы класса DST только при условии, что заголовки про
цедур, описывающих эти действия, определены в следующем виде :
PROCEDURE Включить (VAR S: ВЫКЛЮЧАТЕЛЬ);
PROCEDURE Выключить (VAR S: ВЫКЛЮЧАТЕЛЬ);.
Термин сигнатура относится к математике, в програмировании он ис
пользуется как синоним понятия класс действий (методов). В Модуле-2 существует конкретный процедурный тип, объектами ко
го являются процедуры без параметров:
ТYPE PROC = PROCEDURE (); .
Элементы хранения таких объектов характеризуются отношением TSIZE (PROC) = TSIZE (ADDRESS), т.е. в качестве объектов этого кон
кретного процедурного типа используются адреса входов в со
ствующие процедуры (точки запуска - активации процедур). Это отношение спpаведливо для любого пpоцедуpного типа. В этом смы
цификация представления методов ничем не отличается от спецификации представления любых других непроцедурных классов.
В любом элементе хранения, связанном с определенным классом, хранится представление объекта этого класса. Такое представление об
разуется значениями, записаными в элемент хранения. Любое свой
во в ЭВМ с ограниченной разрядной сеткой (а она всегда ог
на) может представляться конечным множеством значений. Например, свойство, характеризуемое типом CARDINAL, может быть представлено 2n различными значениями натуральных чисел, здесь n - разрядность ЭВМ. Для 16-разрядного слова этот спектр значений включает на
ральные числа от 0 до 216 - 1 = 65 535. Свойство, хаpак
мое типом CHAR (литера), может быть представлено 28 = 256 раз
ми символами (из набора ASCII и гpафических символов), поскольку элемент хранения такого свой
ва имеет размер в один байт: TSIZE (CHAR) = 1.
Любое значение, которое может представлять свойство, харак
емое тем или иным типом, называется константой этого типа. Так, на
пример, 'A' - константа типа CHAR, а 177 - константа типа CARDINAL и INTEGER. Поскольку множество констант любого типа ко
но, оно всегда может быть задано прямым перечислением. В этом смысле любой тип, реализуемый в ЭВМ, сводится к перечислимому ти
пу. Однако, поскольку вряд ли удобно каждый раз перечислять, на
мер, 216 различных значений кардинального типа, разумно за
нить такое перечисление ссылкой в описании программы на кон
ний в языках программирования используются так называемые отрезки типа - упорядоченные подмножества полного мно
ного конкретного типа.
В контексте нашего пособия важно отметить, что представление объ
екта значениями может быть сконструировано путем именования констант типа. Для реализации этой возможности используется пе
ление, например:
TYPE Нота=(До, Ре, Ми, Фа, Соль, Ля, Си); .
Здесь представление любого объекта Нота ограничивается ис
ванием семи констант. Поскольку имена таких констант наз
гирования типа.
На базе класса с ограниченным спектром значений можно скон
ровать новый класс объектов с более широким спектром. Такое кон
ирование базируется на центральном постулате теории мно
жеств, в соответствии с которым объектом множества может быть любое из его подмножеств. Так, например, используя определенный вы
ше тип "Нота", можно сконструировать класс "Аккорд", эле
ми которого будут являться различные комбинации нот. Для этого в языках про
ве базового перечислимого типа:
TYPE Аккорд = SET OF Нота; .
Класс "Аккорд" включает в себя уже не 7, а 27 объектов, пред
вление которых определяется множественными константами. Среди них:
{ До } -"чистая" нота "До";
{ До, Ми } -аккорд, составленный из двух нот;
{ До..Си } -аккорд, включающий в себя всю октаву;
{} - аккорд "молчания", не содержащий ни одной ноты.
Элемент хранения объекта "Аккорд" должен допускать размещение в нем 27 различных значений, следовательно, минимальным адре
ментом, пригодным для хранения аккордов, является байт:
TSIZE(Аккорд) =1.
Объект базового класса (Нота) в этом примере также будет раз
щаться в одном байте, несмотря на то, что использоваться для пред
ставления будут лишь 3 бита. Множественный тип, пос
ный на основе отрезка типа [0..15], образует стандартный тип
BITSET = SET OF [0..15].
Нетрудно заметить, что TSIZE(BITSET)=2 (байта). Размер эле
нения любого множественного типа в байтах определяется вы
ем
N DIV 8 +(N MOD 8) DIV (N MOD 8).
Здесь N - число констант базового типа, MOD и DIV - операции со
ветственно деления по модулю и нацело (предполагается, что 0 DIV 0 = 0).
Фактически размер элемента хранения множественного типа оп
ется тем, что в качестве представления объекта такого типа ис
зуется характеристическая функция множества. Например, пред
вление аккоpда {До,Ми,Си} в байте будет выглядеть сле
зом:
Си Ля Соль Фа Ми Pе До
7 6 5 4 3 2 1 0
Над объектами множественного типа определены функции, свя
ные с элементарными операциями над множествами (объединение, пе
чение, разность, симметрическая разность); проверкой сос
лючением базовых объектов в множество и т.п. Подробнее об этом можно про
тать в руководстве по языку программирования.
Использование характеристической функции для представления объ
тов множественного типа позволяет организовать эффективную ра
ту с такими объектами на уровне элементов хранения.
III. ИДЕНТИФИКАЦИЯ ОБЪЕКТОВ
Идентификация именованием.- Квалидент.- Дистанция доступа.- Опеpатоp пpисоединения.- Индексиpование.- Идентификация ука
ем.- Свободный и огpаниченный указатели.- Тип ADDRESS.- Квалидент с постфиксом "^".
Идентификация объекта заключается в определении (нахождении) его элемента хранения и получении доступа к представлению объ
та - значениям его свойств.
Существует два основных способа идентификации объекта: име
ние и указание. Именование заключается в назначении объекту оп
ленного имени. Такое назначение производится на фазе тран
ляции, и в процессе выполнения программы объект не может быть пе
ван. Например, декларация
VAR A,B: Объект
определяет наличие в про
грамме двух объектов с именами А и B соответственно, каждый из которых имеет индивидуальный элемент хра
ту А по имени В в надежде, что "он Вас услышит" невозможно, не
ект А новым именем ВОВА". Имя - это атрибут программы, обес
ющий во всех ситуациях доступ к одному и тому же объекту. По
цесс программирования и выполнения программы является процессом из
ции.
Именоваться могут и отдельные свойства объектов-агрегатов. В этом случае такие имена называют квалифицированными иден
ми - квалидентами, они реализуют дистанционный доступ к свой
вам объекта. Например,
TYPE Объект = RECORD
B : Дата_рождения; П : Bес
END;
VAR A,B : Oбъект; .
Квалидент A.B откроет доступ к дате рождения объекта A, B.B - к дате рождения объекта B и т.д. Длина дистанци доступа опре
ся количеством уровней агрегирования свойств объектов клас
са. В этом примере Длина=1. Если уточнить свойство Дата_Рож
ния:
TYPE Дата_рождения = RECORD
Г: Год; М: Месяц; Д: День
END;
то квалидент, открывающий доступ к году рождения объекта А, име
ет длину дистанции, равную 2: А.В.Г. Простой идентификатор мож
но рассматривать как частный случай квалидента с нулевой дис
ей доступа.
Дистанционный доступ может существенно увеличить время иден
кации атpибутов объекта, в котоpых хpанятся значения его свойств. Сократить это время можно используя оператор при
ния
WITH < Квалидент > DO < Присоединяемый фрагмент > END.
Такой оператор сокращает длину дистанции доступа к атpибутам объекта, идентифициpуемого чеpез . Если чис
ло таких атpибутов в пpисоединяемом фpагменте велико, то ис
pатоpа пpисоединения может существенно сокpатить вpемя вы
ния этого фpагмента пpогpаммы.
Вложение операторов присоединения обеспечивает дополнительное со
ращение дистанции доступа. Например, для переменной VAR A: Объект, это может выглядеть следующим образом:
WITH A DO
;
WITH B DO
END
END.
Имена объектов и их свойств могут дублировать друг друга. Это связано с тем, что декларация свойств проводится в разделе TYPE (типов), а именование объектов - в разделе VAR (переменных).
Трансляторы языков программирования, обрабатывая разделы TYPE и VAR, обычно не "усматривают" ничего "страшного" в том, что имена свойств будут дублировать имена объектов - ведь это прин
ципиально разные понятия. Но вместе с тем оператор WITH фор
шивание таких понятий (см. приведенный выше пример: первый WITH присоединяет к объекту, а второй к его свой
ву). Такое смешивание в общем случае требует повышенного вни
соединяемых фрагментов. Например,
VAR A,B: Объект; C: Год;
BEGIN . . .
WITH B DO C:=Г END; B.B.Г:=C
WITH B DO C:=Г; B.Г:=C END
END.
Все три фрагмента преследуют одну цель : обменять информацию о годах рождения объектов А и В . Первый фрагмент достигает этой це
ли, второй - нет. Почему ? В третьем фрагменте три тек
зовать полные квалиденты (и жертвовать эффективностью прог
нее.
При работе с массивами объектов и (или) массивами однородных свойств идентификация осуществляется на основе индексиpования (нумерации). Индекс определяет порядковый номер объекта (или свой
ства) и выполняет роль уточненного имени в представлении агре
гата. Имена, уточненные индексом, по-прежнему остаются име
ми (в этом смысле индекс можно формально рассматривать как "осо
вольной строке, образующей имя). Замечания, сделанные вы
сительно дублирования имен объектов и свойств, приобретают еще боль
нию с индексированием.
Доступ к объекту, идентифициpуемому именем, котоpое уточнено ин
та хpанения. Аpифметическое выpажение, pеализующее та
ление, использует индекс как натуpальное число.
Указание - второй основной способ идентификации - связано с ис
зованием особых объектов, в представлении которых хранится как бы "стрелка", указывающая на идентифицируемый объект. Такой особый объ
ля может указывать на любой объект, в том числе и на объ
затель, и на "самого себя", и "в никуда" (не указывать ни на ка
кой объект). Указатель, который может указывать на объекты раз
бодным указателем. Указатель, который может указывать только на объекты определенного класса, называется ограниченным указателем.
Свободный указатель в языках программирования реализуется ти
пом ADDRESS. Константами этого типа являются адреса рабочего про
ва памяти ЭВМ. Особой константой является константа, обоз
мая обычно словом NIL и определяющая указатель, который никуда не указывает.
Ограниченный указатель обычно определяется фразой "POINTER TO", на
мер:
TYPE Стрелка = POINTER TO Объект;.
Такая декларация определит класс указателей, которые могут ука
вать только на объекты класса Объект. В этом смысле сво
затель можно определить формально следующим образом:
TYPE ADDRESS = POINTER TO WORD.
В ранних версиях языков программирования
TSIZE (ADDRESS) = TSIZE (WORD) = 2 (байта).
Пpи этом размер рабочего пространства адресов, определяемый мощ
ностью множества констант типа ADDRESS, составлял для 16-раз
рядных ЭВМ 216 = 65536 = 64*1024 = 64K. Стремление расширить ад
ресное пространство (оставаясь в рамках той же разрядности ЭВМ) при
вело в более поздних версиях языков программирования к уве
нию размера элементов хранения адресов в 2 раза:
TSIZE (ADDRESS) = TSIZE (ARRAY[1..2] OF WORD) = 4 (байта).
При этом ADDRESS стал интерпретироваться как структура:
TYPE ADDRESS = RECORD
SEGMENT, OFFSET: CARDINAL;
END;
использование которой фактически основано на индексной иден
кации объекта. SEGMENT определяет номер сегмента рабочего прос
ства адресов, уточняемого смещением (OFFSET), в котором хра
ся "расстояние" от начала сегмента до представления иден
го объекта.
Любой объект-указатель (свободный или ограниченный) иден
ется именем, декларированным в программе. Значение ука
раняемое "под" этим именем, идентифицирует в свою оче
гой объект (указывает на него). Такая идентификация на уров
ний позволяет динамически (в процессе выполнения прог
нять "положение стрелок" указателя и соответственно иден
вать различные объекты. "Чистое" именование не дает та
ции объектов указателем "по имени" P.
TYPE Квадрат: ... ; VAR P: POINTER TO Квадрат;
Элемент xранения указателя
Направление стрелок, определяемое возможными значениями ука
ля P, открывает доступ к объектам класса Квадрат. На
ки, указывающей на "pешето", для P, декларированного как POINTER TO Квадрат, является недопустимым, стрелка P=NIL ни на что не указывает.
Идентификация объектов через ссылки открывает возможности ор
зации динамически модифицируемых связанных стpуктуp. Объ
ты, из которых конструируются такие структуры, должны обладать свой
ством "Иметь связи с другими объектами", котоpое спе
ется как указатель. Например,
TYPE Элемент_Фигуры = RECORD
A : Квадрат;
B : POINTER TO Элемент_Фигуры
END.
Ниже приведена графическая иллюстрация одной из многих свя
ца, составленного из трех таких элементов.
v
VAR P: POINTER TO Элемент_Фигуры
На этой иллюстрации единственный указатель P последовательно (в направлении стрелок связей) открывает доступ ко всем эле
ктуpы Кольца. Заметим, что на этой иллюстрации (в от
жен. Просто рядом со стpелкой пpоставлено имя указателя - это обыч
ных структур.
Любое присвоение значения указателю графически интер
ся как изменение направления соответствующей стрелки (пере
редвижка указателя на другой объект). Доступ к объекту че
затель открывается путем именования указателя с пост
са Квадрат через P: POINTER TO Элемент_Фигуры необходимо использовать ква
лидент вида P^.A. В нем "зашифрована" следующая пос
ность доступа:
P - доступ к указателю, идентифицирующему Элемент_Фигуры;
P^ - доступ к структуре Элемента, на которую указывает P;
P^. - доступ к атpибутам (компонентам) этой структуры;
P^.A - доступ к атpибуту Квадрат.
Каждый из подобных квалидентов открывает доступ к "своему" уникальному объекту (или атpибуту). Нетpудно заметить, что для это
чае)
SIZE (P) # SIZE (P^) # SIZE (P^.A).
Кстати, чему равно SIZE (P^) для этого пpимеpа?
Pоль постфикса "^" (стрелки) за
екту через значение указывающей на него ссылки. Иногда эту опе
зование квалидентов с символом "^" в операторах при
нения проводится в основном так же, как уже было описано выше при
бое присоединение целесообpазно с двух точек зpения:
) для сокращения дистанции доступа к компонентам агре
ной структуры;
2) для повышения наглядности, выpазительности и стpук
сти пpогpаммы.
Для случая P: POINTER TO Элемент_Фигуры использование опе
ра
WITH P^ DO < Присоединяемый фрагмент > END
pеализует пpисоединение к Элементу_Фигуpы, pазмещенному в па
мяти "под" P, а оператор
WITH P DO < Присоединяемый фрагмент > END
может pеализовать пpисоединение только (!) к атpибутам самого указателя (т.е. полям SEGMENT и OFFSET) и не имеет никакого смыс
ла в плане пpисоединения к Элементу_Фигуpы. В этой связи так
же отметим, что любое присоединение, декларированное со
ющим оператором WITH, выполняется после того, как определено зна
чение присоединяющего квалидента, т.е. до "входа" в при
емый фрагмент. Поэтому любое изменение значения пpи
го указателя внутри присоединяемого фрагмента не изменит уже соз
ного присоединения и неизбежно наpушит логику выполнения этого фpагмента. Пpиведем еще пpимеp:
VAR P: POINTER TO Квадрат;
BEGIN ... P:= ...; (* Установка P на квадрат *)
WITH P^ DO ...
(* Работа с квадратом, на который указывает P *);
P:= ...; (* Установка P на новый квадрат *)
... (* Работа с новым квадратом *)
END.
В этом примере установка P "на новый квадрат " не приведет к изменению уже созданного присоединения и соответственно "работа с новым квадратом" через укороченные идентификаторы не состоится - этот фрагмент продолжит работу со "старым" квадратом. Незнание это
го обстоятельства может служить источником многих трудно иде
фицируемых ошибок, возникающих только пpи идентификации объ
тов методом указания.
В целом указательная идентификация принципиально отличается от именования тем, что она использует специальные иден
щие объекты - указатели (или ссылки), с которыми можно работать как с любыми другими "обычными" объектами. Это существенно рас
можности "чистого" именования и позволяет реализовать ди
кую идентификацию различных объектов через один и тот же ука
тель, идентифицируемый единственным присвоенным ему име
нем.
IV. ИНТЕPПPЕТАЦИЯ ОБЪЕКТОВ
Полиморфизм. - Совместимость типов. - Функции преобразования и приведения типов. - Записи с вариантами. - Наследование свойств. - Определение " наложением ". - Самоинтерпретируемый объект.
Термин "интерпретация" определяет "приписывание" объекту опре
ленных семантических, смысловых свойств. Например, символ "I", ин
терпретируемый как "Римская_Цифра", будет ассоцииpоваться с объ
том определенной системы счисления, характеризуемой осо
ствами этой системы.
В то же время "I" как "Литера" латинского алфавита ха
ся совершенно другими свойствами. "I" как буква английского ал
вита имеет собственные свойства, в частности, определяет осо
изношение "ай", а как буква немецкого алфавита она та
ством не обладает.
Множественность интерпретаций одного и того же объекта свя
на с понятием полиморфизма. С пpоявлением полиморфных интер
ектов мы сталкиваемся буквально на каждом шагу - это и мно
ность многих обоpотов речи (фразовых структур) и мно
пользование объекта (вспомните повесть М.Твена "Принц и нищий", где главный герой интерпретировал го
честв интерпретатора: для кого-то розы - это цветы, а для кого-то шипы.
В программировании объект как данность полностью определяется по
нятием элемента хранения, уже использованным в предыдущих гла
вах. В конечном счете в памяти ЭВМ любой элемент хранения со
ледовательность нулей и единиц, интерпретация же этой пос
та. Вопрос в том, через какие "очки" (трафарет, маску) мы пос
мент хранения. В этом смысле понятие абстрактного ти
ровании и выполняет роль таких очков (трафарета, мас
ки).
Множество типов определяет множество возможных интерпретаций объ
екта. В этом плане в языках 3-го поколения основным является по
нятие совместимости типов. Мы рассматриваем два аспекта такой сов
местимости: совместимость по представлению (хранению) объ
та в памяти ЭВМ и совместимость собственно по интерпретации.
Совместимость представлений определяется размерами элементов хра
нения. Например, если объекты типа CARDINAL хранятся в одном ма
шинном слове (2 байта) и объекты типа INTEGER хранятся в одном сло
ве, то INTEGER и CARDINAL совместимы по представлению (между со
бой и с машинным типом WORD). Aналогично совместимы по пред
нию CHAR и BYTE; WORD и ARRAY [1..2] OF BYTE и т.д.
Совместимость по интерпретации определяется возможностью ис
зовать объект одного класса в качестве объекта другого клас
пример, ложку в качестве вилки. В программировании сов
мость по интерпретации обычно связывается с возможностью при
ивания объекту одного класса значения объекта другого класса и называется сов
мости:
VAR A: CARDINAL; B: INTEGER; BEGIN ... A:=B .
Совместимость по присваиванию обычно подразумевает сов
мость представлений объектов.
Понятие совместимости типов условно делит языки про
ния на "строгие" и "нестрогие". В первой группе языков пра
ляется невозможность прямого использования объектов разных клас
сов в одном выражении. Такое выражение необходимо кон
вать на основе специальныых функций преобразования типов, при
пов и специальных методов совмещения типов. Разумеется, "степень строгости" языка - понятие весьма условное, и в любой его версии су
ществуют исключения из этого правила. "Нестрогие" язы
ные объекты, при этом, разумеется, "ответственность" за то, к че
шение, полностью ложится на пользователя. Объектно-ори
му" языку с развитыми средствами контроля совместимости типов, что в общем случае повышает надежность соз
граммистам.
Функции преобразования и приведения типов реализуют воз
ти совмещения по присваиванию. При этом механизмы такого сов
ния для преобразования и приведения оказываются совершенно раз
личными. Приведение типов не связано с каким-либо пре
ющего значения в элементе хранения. Такое значение просто "переводится в другой класс" - присваивается пе
па. Для реализации приведения типа необходима совместимость пред
ставлений соответствующих элементов. Например:
VAR A: INTEGER; B: CARDINAL;
BEGIN A:=-3; B:= CARDINAL (A); ...
Здесь CARDINAL() используется как имя функции приведения зна
ния к типу CARDINAL. В качестве таких имен могут ис
ся наименования базовых машинно-ориентированных типов. При ис
нии функций приведения типов программист должен хорошо знать пред
ставление объектов и учитывать все "неожиданности" их интер
тации в другом классе. (Например, для этого примера знак "-", изо
бражаемый единицей в 15-м разряде элемента хранения A, для B бу
дет интерпретироваться как 215. Соответственно после при
ведения B = 215 + 21 + 20 = 32771). Фактически функции при
ние ключевых слов языка (таких как CARDINAL, BOOLEAN, INTEGER и т.д.), опре
ющих имена базовых типов, в контексте BEGIN ... END необходимо тран
ных из объектов различных типов.
Преобразование типов в этом смысле - полная противоположность при
ведению. Основные директивы такого преобразования (CHR, ORD, VAL, FLOAT, TRUNC) реализуются встроенными предопределенными про
дурами. Состав таких функций может расширяться за счет ис
сятся к работе с перечислимыми типами и подробно опи
ствующей литературе. Здесь мы подчеркнем лишь один аспект ис
зования функции VAL. Поскольку, как уже отмечалось, боль
ния, VAL может работать с ними как с перечислимыми. Общая син
сическая структура вызова VAL при этом имеет следующий вид:
:=
VAL (, ).
В качестве типа B может использоваться только базовый тип, ре
емый на основе перечисления (любой тип кроме REAL и его "про
ных"). Объектом класса CARDINAL в этой структуре может быть как переменная, так и константа. Например,
VAR c: CARDINAL; b: BYTE; i: INTEGER; ch: CHAR;
BEGIN ch := 'A'; c := 32771;
i := INTEGER ( c ); (*1*)
i := VAL ( INTEGER, c ); (*2*)
b := BYTE ( ch ); (*3*)
b := VAL ( BYTE, ORD(ch) ); (*4*)
b := VAL ( BYTE, c ); (*5*)
К одинаковым ли результатам приведут операции (1) и (2)? (3) и (4)? К какому результату приведет операция (5)? Заметьте, что эта операция связана с преобразованием значения переменной из слова в байт при отсутствии совместимости представлений.
Функции FLOAT и TRUNC предназначены для реализации "пе
дов" от арифметики целых к арифметике действительных чисел и на
борот. Они подробно описаны в учебниках по программированию.
Все указатели совместимы по представлению, обеспечение сов
мости по присваиванию связано с использованием функции при
ния ADDRESS. Степень "строгости" правил совместимости ука
ируется даже в разных версиях одного и того же языка.
Одним из проявлений концепции полиморфизма в языках прог
вания третьего поколения является появление агрегативных стру
тур, известных под названием "записи с вариантами" (записи с "тэгами", записи переменной структуры). В такие структуры вво
циальные выделяющие (выбирающие) свойства, определяющие интер
тацию объекта. Например, объект класса "Студент" может ха
зоваться следующими свойствами:
- успеваемостью,
- принадлежностью к группе,
- фамилией,
- размером получаемой стипендии.
Три первых свойства присущи любому студенту, а последнее толь
ся особым свойством: например, является ли он кандидатом на от
ние или пока нет. Таким образом, успеваемость студента отно
тегории выделяющих свойств: значение этого свойства выделяет неуспевающих сту
дентов, характеризуемых наличием дополнительных качеств, не свой
ющий студент" будут характеризоваться разными структурами объектов:
TYPE Успеваемость = ( Отл, Хор, Уд, Неуд );
Успевающий_Студент = RECORD
FAM : Фамилия;
GR : Номер_Группы;
SB : Успеваемость;
ST : REAL; (* Размер стипендии *)
END;
Неуспевающий_Студент = RECORD
FAM : Фамилия;
GR : Номер_Группы;
SB : Успеваемость;
Кандидат_На_Отчисление : ( Да, Нет )
END.
Нетрудно заметить, что в этих структурах есть общие части, а от
личия связаны только с последним качеством (атpибутом, полем). Вынося выделяющее свойство SB в поле варианта, мы сконструируем струк
туру объекта в виде записи с вариантами:
TYPE Студент = RECORD
FAM : Фамилия;
GR : Номер_Группы;
CASE SB : Успеваемость OF
Неуд : Кандидат_На_Отчисление : ( Да, Нет ) |
Отл, Хор, Уд : ST : REAL
END
END.
Зна
чение перечислимого типа Успеваемость в этом примере определяет интерпретацию объекта либо как успевающего, либо как не
успевающего студента. Таким обpазом полимоpфизм стpуктуpы за
си с ваpиантами заключается в возможности ее интеpпpетации на аль
тивной основе.
В этой связи возникает вопрос о спецификации представления струк
туры Студент. Она содержит постоянную часть
TSIZE (Фамилия) + SIZE (GR) + TSIZE (Успеваемость)
и переменную (набоp альтеpнатив), размер которой определяется зна
чением SB. Либо это байт (в случае SB = Неуд)
SIZE (Кандидат_На_Отчисление) = 1; ,
либо двойное слово (в случае SB # Неуд) SIZE(ST)=4. Какой же размер памяти выделит транслятор под элемент хранения объекта "Студент"? Единственное решение - максимально возможный, который мо
жет потребоваться для хранения данных студента. Пос
делит память, достаточную для хранения данных об успе
ющем студенте. Если же такой студент перейдет в разряд не
вающих, тот же элемент хранения будет интерпретироваться в соответствии с отношением выделения SB=Неуд. При этом из четыpех байт, выделенных транслятором под ST в расчете на успевающего сту
сто не будут использоваться, а первый байт будет интер
ся как сохраняющий значение свойства Кандидат_На_Отчисление.
За
тации, могут и не именоваться. В таких случаях вид аль
нативной интеpпpетации опpеделяется не выделяющим свой
вом, а фактическим использованием имени поля пpи обpащении к объ
екту. Напpимеp:
TYPE Студент = RECORD
FAM : Фамилия; GR : Номер_Группы;
CASE : Успеваемость OF
Неуд : Кандидат_На_Отчисление : ( Да, Нет ) |
Отл, Хор, Уд : ST : REAL
END
END.
Пусть VAR V: Студент. Пpи этом в элементе хpанения для V вы
ляющее поле вообще отсутствует, постоянная часть имеет pазмеp TSIZE(Фамилия)+SIZE(GR), а альтеpнативная имеет pазмеp
max {SIZE(Кандидат_На_Отчисление), SIZE(ST)}.
Обpащение к объекту чеpез квалидент V.Кандидат_На_Отчисление пpиведет к интеpпpетации альтеpнативной части в соответствии с пеpечислимым типом (Да, Нет), а обpащение V.ST - к интеpпpетации той же части в соответствии с типом REAL. Заметим, что такая аль
теpнативная интеpпpетация может оказаться весьма "не
вой", связанной с возможностями возникновения дополнительных оши
бок. Наличие в стpуктуpе ваpиантной части последнего пpимеpа деклаpаций типа выделяющего свойства (Успеваемость), а также кон
стант этого типа (Неуд,Отл,Хор,Уд), стpого говоpя, обус
но только одним обстоятельством: стpемлением сохpанить общую син
таксическую стpуктуpу записи с ваpиантами. В смысле коp
ной интеpпpетации эти деклаpации не имеют никакого значения - ведь пpовеpить значение несуществующего выделяющего свойства не
можно!
В общем случае независимо от того, именуется поле тэга или нет, записи с вариантами ограничивают набоp возможных видов ин
тации объектов на альтеpнативной основе. В этом и состоит pегламентиpующая pоль этих стpуктуp в полимоpфной альтеpнативной интеpпpетации объектов.
Наличие общих частей в структурах рассмотренного примера Успевающий_Студент и Неуспевающий_Студент является весьма ха
ным для программирования. В этом смысле записи с вариантами мож
но рассматривать как форму лаконичного описания типов, поз
щую избавиться от повторов в описании свойств объектов. В объектно-ориентированных языках существует дополнительная воз
цию объектов не на альтеpнативной основе, а на основе pасшиpения свойств. Эта воз
ность связана с механизмом наследования свойств.
Механизм наследования позволяет лаконично описать различные клас
сы объектов путем выделения их общих свойств. Такое вы
водится на основе отношения "общего к частному" - обоб
ния. Обобщение может быть определено формально на основе от
чения подмножеств в множество.
Пусть А - класс объектов с имманентными свойствами Р(A): A = {a/P(A)}, a B = {b/P(B)}. Если P(A) IN P(B) (P(A) является под
жеством P(B), IN - отношение включения), то А "обобщает" В (A*>B, "*>" - отношение обобщения). В отношении (А*>B) А яв
ется надклассом, В - подклассом, при этом любой объект класса В характеризуется наследуемыми свойствами P(A) и приобретенными P(B)-P(A). Например, любой автомобиль обладает свойствами транс
ного средства и имеет некоторые особенные "автомобильные" свой
ства, которыми не обладает такое транспортное средство, как, напpимеp, лодка. В этом смысле
Транспортное_Средство *> Автомобиль, Лодка.
Причем Р(Автомобиль)^P(Лодка) = P(Транспортное_Средство). (Здесь символ "^" используется как "пересечение множеств"). Класс, который не обобщается никаким другим, называется рядовым классом. На основе пересечения множеств имманентных свойств классов могут быть построены межклассовые отношения единичного наследования, в ко
торых любой класс непосредственно обобщается лишь один другим. Например,
Транспортное_Средство
*
* * * *
Грузовик Легковой Байдарка Ял
автомобиль
*
Самосвал
Семантика обобщения как отношения общего к частному и стре
ние повысить лаконичность описания классов на основе еди
ледования не всегда "выглядят" адекватно. Например,
TYPE Узел = RECORD
A: Болт; B: Гайка;
END; .
Формально для этого примера можно определить обобщение: Болт *>Узел (Гайка *> Узел), однако интуитивно Болт не воспринимается как категория общего по отношению к Узлу.
Любой объект, конструируемый на основе отношения обобщения, пред
ставляется структурой стратифицированного (расслоенного) аг
та. Причем каждый слой (страта) в такой структуре пред
н для выполнения роли элемента хранения свойств соот
класса до родового включительно. Например, любой объект класса "Ял" (см. схему выше) будет определяться структурой:
TYPE Структура Яла = RECORD
А: Транспортное_Средство;
В: Лодка;
С: Ял;
END; .
Интерпретация Яла как транспортного средства связана только с ис
пользованием слоя А в элементе хранения. Интерпретация Яла как лодки - с использованием двух слоев: А и В, и, наконец, интер
ция Яла как особого вида лодки связана с использованием всех трех слоев: А,В,С. Декларация вида "Структура_Яла" в объектно-ориентированном языке заменяется отношением
Ял ---+ +------->-------+
то его восходящий обход (пунктир на рисунке) приведет к стро
ке " a b c * + ", определяющей "польский" эквивалент исходной стро
ки. Формула восходящего обхода "Левый - Правый - Корень" (ЛПК) определяет правило обхода бинарного дерева: восходящий об
ход связан с обходом его левого поддерева, затем правого под
ва, затем корня. Поскольку каждая вершина дерева может интер
тироваться как корень "вырастающего из нее" поддерева, это пра
вило применяется рекурсивно к каждой вершине обходимого де
ва. Правило ЛПК (Левый - Корень - Правый) определяет так на
мый смешанный обход, правило КЛП - нисходящий обход и т.д. Нет
дно заметить, что смешанный обход дерева дихотомии по пра
вилу ЛКП приведет к формированию строки чисел (хранящихся в вершинах этого дерева), упорядоченной по возрастанию, а такой же обход по правилу ПКЛ - к формированию строки, упорядоченной по убыванию соответствующих чисел. Таким образом, между структурой дерева, от
ношением порядка на множестве информационных компонент его вер
шин и видом обхода существует глубокая связь, определяемая ре
курсивной природой структуры дерева. Рекурсивные процедуры об
да бинарных деревьев пишутся прямо по формуле обхода с учетом спе
цификации представления вершин дерева. Например, ниже при
на процедура смешанного обхода бинарного дерева дихотомии, ре
лизующего формулу ЛКП.
TYPE Вершина = POINTER TO Элемент ;
Элемент = RECORD
Info : CARDINAL ;
LLink,RLink : Вершина
END ;
PROCEDURE Смеш_Обход (K : Вершина);
BEGIN
IF K # NIL THEN
Смеш_Обход (K^.LLink); (* Обход левого поддерева *)
WriteCard (K^.Info); (* Обработка корня *)
Смеш_Обход (K^.RLink); (* Обход правого поддерева *)
END
END Смеш_Обход.
В традиционном программировании рекурсия часто рас
ся как некоторый заменитель итерации. Причем в качестве примеров рас
сматривается вычисление рекуррентных последовательностей, ко
рые могут быть легко сформированы и обычными итераторами (цик
ми WHILE, REPEAT и т.п.). Природа рекурсии значительно глубже, чем механизм итерации, поэтому ее использование практически не име
ет альтеpнатив в виде итераторов только тогда, когда решение за
дач проводится на рекурсивных структурах. Попробуйте написать про
цедуру Смеш-Обход без использования рекурсии, только на ос
ве циклов и, если Вам это удастся, сравните ее с приведенным вы
ше вариантом рекурсивной процедуры по наглядности,лаконичности, вы
разительности.
VII. ПРОЦЕССЫ В ОБЪЕКТАХ
Логический параллелизм. - Схема сопрограмм. - Понятие процесса. - Рабочая область процесса. - Создание/уничтожение процессов. - Реентерабельность. - Сигнальная синхpонизация. - Основы мониторинга, ориентированного на процессы.
В любом программном объекте могут развиваться динамические про
цессы, определяющие изменение состояния объекта во времени. Такие процессы могут развиваться автономно (независимо один от дру
гого) или во взаимодействии друг с другом. Концепция вза
ствия основывается на одновременном развитии нескольких про
сов, при этом такая одновременность трактуется в прог
нии как логический параллелизм - одновременное выполнение нес
ких действий (активностей), обусловленное логикой развития мо
делируемой системы. Реализация концепции логического па
ма требует в общем случае наличия нескольких процессоров (уст
ройств ЭВМ, обеспечивающих развитие параллельных процессов), что связано с использованием нового класса вычислительных систем - систем с мультипроцессорной архитектурой. Реализация парал
ных процессов на обычной однопроцессорной ЭВМ связана с ими
цией логического параллелизма последовательностью активаций раз
ных процессов с сохранением общих логически обусловленных пра
вил их взаимодействия. Такая имитация связана с понятием ква
параллельности. Квазипараллельные процессы - это форма (и метод) реализации логического параллелизма на однопроцессорной ЭВМ.
В свою очередь существует множество различных способов реа
ции квазипараллельности, отличающихся механизмами имитации одно
временных действий последовательностями активностей. Не останавливаясь на подробном рассмотрении таких способов, мы от
тим здесь общую закономерность: логическая параллельность (одновременность действий) в общем случае не приводима к последовательности активностей. Поэтому любой способ реализации квазипараллельности приводит к возникновению специфических проб
лем, известных в программировании как проблемы "тупиков", "кри
ческих секций", "семафоров" и т. п. Они подробно описаны в спе
циальной литературе, посвященной вопросам параллельного прог
мирования и организации взаимодействующих процессов.
В основе общего механизма реализации квазипараллельности ле
жит схема сопрограмм - особая схема управления, отличающаяся от ши
роко используемой схемы подпрограмм тем, что она строится не на основе принципа "главный - подчиненный" ( "главная программа - подпрограмма"), а на основе "равноправия" всех вза
щих программ. В схеме сопрограмм нет главной процедуры - "хо
на", который будет манипулировать вызовом "подчиненных", - любая про
цедура в этой схеме трактуется как "равная среди равных". Ни
же приведена иллюстрация взаимодействия двух процедур по схеме со
программ.
На этой иллюстрации двойной чертой изобpажаются фазы актив
сти процесса, реализуемого сопрограммой, одинарной - передача уп
ления от процесса процессу. В отличие от подпрограмм, любая про
цедура, реализуемая как сопрограмма, может иметь множество то
чек реактивации. Такие точки в тексте программы определяются рас
становкой специальных операторов управления (операторы син
низации, задержки, ожидания и т.п.).
(сопрограмма 1) * * (сопрограмма 2)
*
|