Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Алгоритмические языки высокого уровня. Курс лекций

.pdf
Скачиваний:
0
Добавлен:
12.08.2026
Размер:
940 Кб
Скачать

6. МОДУЛИ И УСТРОЙСТВА

Часто используемые подпрограммы хранятся в виде собственных библиотек. Библиотеки организуются в виде модулей. Для того что- бы использовать библиотеки (модули) достаточно задать в програм- ме описательное предложение

uses <список имен модулей>;

Текст модуля обычно располагается в файле, потом транслируется в файл с расширением *.tpu. На этапе компоновки (сборки) задачи модуль подключается к оттранслированной программе.

Применение модулей позволяет повысить скорость компиляции программы, поскольку модули хранятся в готовом скомпилирован- ном виде и перекомпилируются только при наличии изменений в их исходном тексте. Модули очень удобны для построения собственных процедур и функций, которые могут использоваться разными про- граммами, не требуя никаких переделок. Модульность позволяет создавать программы практически любого размера.

Чтобы подключить модуль к программе, его требуется предвари- тельно скомпилировать. Результат компиляции модуля хранится на диске в отдельном файле с расширением *.tpu.

Описание модулей

Исходный текст каждого модуля хранится в отдельном файле с расширением *.pas. Модуль состоит из секций (разделов). Общая структура модуля имеет вид:

Unit Имя; {Заголовок модуля} Interface {Интерфейсная часть модуля}

{Описание глобальных переменных модуля видимых извне} Implementation {Секция реализации модуля} {Описание локальных (внутренних) элементов модуля} Begin {Секция инициализации модуля}

{Может отсутствовать}

End.

Имя файла, в котором хранится модуль, должно совпадать с име- нем, заданным после ключевого слова Unit.

В интерфейсной секции модуля определяются константы, типы данных, переменные, а также заголовки процедур и функций. Полно- стью же подпрограммы описываются в секции реализации, скрытой от пользователя модуля. Здесь перечисляются используемые модули со словом USES.

131

В секции реализации модуля описываются подпрограммы, заго- ловки которых приведены в интерфейсной части. Заголовок подпро- граммы должен быть идентичным указанному в секции интерфейса и состоять только из ключевого слова Procedure или Function и имени подпрограммы. Для функции также указывается её тип. Кроме того, в этой секции определяются константы, типы данных, перемен- ные и внутренние подпрограммы. Они используются внешними эле- ментами модуля и видны только в части реализации, т.е. из програм- мы, к которой подключен этот модуль, обратиться к ним нельзя.

Секция инициализации предназначена для присваивания на- чальных значений переменным, используемым в модуле или в про- грамме, к которой он подключен. Операторы, расположенные в сек- ции инициализации модуля, выполняются перед операторами основ- ной программы. Если секция инициализации в модуле отсутствует, то в конце ставится END., а слово BEGIN пропускается.

Пример программы

Описание: программа подсчета средних значений двух массивов. {Модуль: подпрограмма вычисления среднего арифметического

массива чисел}

Unit Average_; INTERFACE

Const n=10;

Type mas=array [1..n] of real; Procedure average(x:mas; var av:real); IMPLEMENTATION

Procedure average(x:mas; var av:real); Var i:integer;

Begin av:=0;

for i:=1 to n do av:=av+x[i]; av:=av/n

end;

End.

Список параметров подпрограммы в разделе IMPLEMENTATION указывать не обязательно.

{основная программа подсчет средних значений двух массивов}

Program Test;

Uses Average_,CRT; Var a,b: mas;

i :integer; av_a, av_b:real;

132

Begin ClrScr;

randomize;{Подключение генератора случайных чисел} for i:=1 to n do begin

a[i]:=random; {Заполнение массивов} b[i]:=random

end;

average(a, av_a); {Подключение процедуры из модуля} average(b, av_b);

writeln(av_a:5:3,' ',av_b:5:3); readln

End.

Кроме собственных библиотек пользователя существуют стан- дартные библиотеки Pascal. Среди этих библиотек можно назвать следующие: System (ввиду исключительной важности подключа- ется автоматически к любой программе и содержит основные под- программы), Dos (обеспечивает интерфейс с программами опера- ционной системы), Crt (содержит средства управления монитором в текстовом режиме), Graph (содержит средства управления мони- тором в графическом режиме), Printer (обеспечивает связь с пе- чатающим устройством), Overlay (содержит средства для созда- ния и управления перекрывающимися/оверлейными программами).

133

7. ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ

Объектно-ориентированная концепция создания программ заро- дилась примерно в одно и то же время со структурной методологией (в середине 60-х годов прошлого века) и имела аналогичную цель обеспечение дисциплины программирования при разработке боль-

ших программных комплексов. Объектно-ориентированное про-

граммирование (ООП) – это методология программирования, которая основана на представлении программы в виде совокупности объек- тов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию на принципах на- следуемости. ООП базируется на трех основных понятиях: инкапсу- ляция, наследование и полиморфизм.

Объект осязаемая сущность, которая четко проявляет свое по- ведение. Не лишен скрытого смысла студенческий ответ: «Объект это все». Инкапсуляция это объединение в рамках единого целого (объекта) данных (характеристик объекта) и действий (процедур и функций) по обработке этих данных. В терминах ООП данные назы- ваются полями, а процедуры и функции методами, т.е. можно ска- зать, что объект состоит из полей и методов. Инкапсуляция позволя- ет в максимальной степени изолировать объект от внешнего окруже- ния. Объект (а точнее экземпляр объекта) сам «знает» о себе все и «умеет» манипулировать этими знаниями. При этом обмен данными между объектом и программой (или другим объектом) сведен к ми- нимуму.

Наследование это свойство объектов порождать своих потом- ков. Наследование это такое отношение между объектами, когда один объект повторяет структуру и поведение другого. Объект- потомок автоматически наследует от родителя все поля и методы, может быть дополнен новыми полями, а методы предка могут быть заменены или дополнены новыми. Объект может иметь сколько угодно потомков, а вот предок может быть только один. Это дает возможность создавать довольно-таки сложную «ветвистую» (древо- видную) иерархическую структуру объектов в программе.

Полиморфизм это свойство родственных объектов (т.е. объек- тов, имеющих общего родителя) решать схожие задачи разными спо- собами. Поскольку поведение объекта определяется набором его ме- тодов, то программист, изменяя алгоритм того или иного метода,

134

может придавать потомкам специфические свойства, отсутствующие у родителя. Для этого родительский метод должен быть перекрыт новым. В результате объектродитель и объектпотомок будут со- держать два разных метода, но с одинаковыми именами. В Turbo Pascal полиморфизм достигается не только за счет наследования и перекрытия методов, но и использования виртуальных методов.

7.1. Объектные типы и экземпляры

Переменные объектных типов (экземпляры объектов) представ- ляют собой структурированный (комбинированный) тип данных, яв- ляющийся совокупностью информационных полей (переменных лю- бого типа) и методов (процедур и функций).

Объектные типы описываются в разделе Type программы с ис- пользованием зарезервированного (ключевого) слова object:

Type

<имя объектного типа> = object <информационные поля> объекта (переменные)>

<методы объекта (заголовки процедур и функций)> end;

Опишем объект, который будет представлять собой позицию на графическом экране. Для этого необходимо объявить два поля (X и Y – координаты точки) и несколько методов: для инициализации объекта, получения его координат, уничтожения и т.п.

Type

TLocation = object

X,Y : Word; {Координаты позиции на экране} Procedure Init(InitX, InitY : Integer);

{Инициализация объекта}

Function GetX : Word; {Возвращает координату Х} Function GetY : Word; {Возвращает координату Y} Procedure GetCoords(Var CoordX, CoordY : Word); {Возвращает обе координаты}

Procedure Done; {Уничтожает объект} End;

Поля объекта описываются таким же образом, что и поля записи, а для описания методов объекта используются только заголовки про- цедур и функций. Тела методов всех объектов, объявленных в про- грамме, описываются в разделе реализации процедур и функций про- граммы (в любом месте и в любой последовательности, но обяза- тельно ниже «своего» объекта). Синтаксически реализация метода

135

выглядит так же, как и реализация «обычной» процедуры или функ- ции за одним исключением: перед именем метода через точку необ- ходимо указать имя объекта, которому он принадлежит:

Procedure <Имя объекта>.<Имя метода>(<Формальные парамет-

ры>); <Раздел локальных описаний метода (процедуры)> begin

<Операторная часть метода (тело процедуры)> end;

Описание методов объекта TLocation:

Procedure TLocation.Init(X,Y : Word);

begin

X := InitX;

Y := InitY end;

Function TLocation.GetX : Word; begin

GetX := X end;

Function TLocation.GetY : Word; begin

GetY := Y end;

Procedure TLocation.GetCoords; begin

CoordX := GetX;

CoordY := GetY end;

Procedure TLocation.Done; begin

end;

Замечания: 1) при реализации методов не обязательно повторять весь заголовок подпрограммы, достаточно только имени без списка формальных параметров (как это сделано для метода GetCoords); 2) метод объекта может обращаться не только к полям, но и к другим методам (как это сделано в методе GetCoords); 3) в данном объекте присутствует метод Done (пустой), который «ничего не делает», по- скольку позицию на экране уничтожить нельзя.

7.2.Директивы private и public

Спомощью директивы private при описании объекта можно ограничить область видимости полей и методов. Поля и методы объ-

136

екта, описанные в секции private, будут доступны только в преде- лах той программной единицы (программы или модуля), где описан соответствующий объект. Такие поля и методы принято называть приватными, т.е. если описать объект TLocation следующим обра- зом:

Type

TLocation = object private

X, Y : Word; public

...

end;

и разместить это описание в модуле, то после подключения модуля к программе программист не сможет «напрямую» изменять значения этих полей (X, Y). Он будет вынужден вызывать соответствующие методы. По умолчанию поля и методы, описанные непосредственно за ключевым словом object, считаются общедоступными. Дирек- тива же public просто отменяет действие директивы private, т.е. все последующие поля и методы будут общедоступными.

Директивы private и public могут использоваться в любом порядке сколько угодно раз, но принято при описании объектного типа после зарезервированного слова object объявлять общедос- тупные поля и методы, и только затем после директивы private приватные.

7.3. Наследование

Если объектный тип создается «на базе» другого существующего объекта, то имя родительского типа должно быть указано в скобках после слова object при описании потомка:

Type

<Потомок> = object(<Родитель>) <Добавленные поля> <Добавленные и переопределенные методы> end;

Такие объекты автоматически наследуют от родителя его поля и методы. Поля могут быть добавлены (но не переопределены), а ме- тоды переопределены и добавлены.

Создадим новый объект точку на основе существующего объек- та позиции на графическом экране. Новый объект, кроме коорди- нат, будет характеризоваться еще и цветом, может быть видимым

137

или невидимым, перемещаться по экрану. Для этого нам понадобит- ся добавить два свойства и несколько методов, а также переопреде- лить методы Init и Done:

Type

TPoint = object(TLocation) Clr : Byte; {Цвет}

Visib : Boolean; {Видимость}

Procedure Init (InitX, InitY:Word; InitColor:Byte); {Переопределяем метод инициализации - добавляем цвет} Function GetColor : Byte; {Возвращает цвет}

Function IsVisib : Boolean; {Возвращает видимость} Procedure Show; {Делает видимым}

Procedure Hide; {Делает невидимым}

Procedure ChangeColor(NewColor : Byte); {Меняет цвет} Procedure MoveTo(NewX, NewY : Word);{Перемещает в новую

позицию}

Procedure Done; {Переопределяем для уничтожения объекта} end;

Описание реализации методов:

Procedure TPoint.Init (InitX, InitY:Word; InitColor:Byte);

begin

X := InitX;

Y := InitY;

Clr := InitColor; Visib := False

end;

Этот метод добавляет новую функциональность по сравнению с предыдущим. Первые две строки тела метода повторяют (причем полностью) операторную часть метода Init объекта TLocation, две следующие новые. И хотя такой вариант переопределения ме- тода тоже работоспособен, в данном случае его можно упростить с помощью такого механизма, как вызов метода непосредственного родителя из метода потомка. Для этого в Turbo Pascal есть специаль- ное зарезервированное слово inherited (в переводе с английско- го унаследованный).

Procedure

TPoint.Init

(InitX,

InitY:Word;

Init-

Color:Byte);

 

 

 

 

begin

 

 

 

 

inherited Init(InitX, InitY); Clr := InitColor;

Visib := False end;

138

Вместо слова inherited можно указать имя объекта-родителя:

TLocation.Init(InitX, InitY);

Function TPoint.GetColor : Byte; begin

GetColor := Clr; end;

Procedure TPoint.Show; begin

Graph.PutPixel(X, Y, Clr); Visib := True

end;

Procedure TPoint.Hide; begin

Graph.PutPixel(X, Y, Graph.GetBkColor); Visib := False

end;

Procedure TPoint.IsVisib : Boolean; begin

IsVisib := Visib end;

Procedure TPoint.ChangeColor(NewColor : Byte); begin

Clr := NewColor;

If IsVisib then Show end;

Procedure TPoint.MoveTo(NewX, NewY : Word); Var Status : Boolean;

begin

Status := IsVisib; Hide;

X := NewX;

Y := NewY;

If Status then Show end;

Procedure TPoint.Done; begin

Hide;

Clr := Graph.GetBkColor end;

Дочерний объектный тип «точка» – потомок родительского объ- екта «позиция» создан.

7.4. Полиморфизм

Создадим еще один дочерний объектный тип потомок объекта TPoint, который будет представлять собой окружность. X и Y пре-

139

вращаются в координаты центра, и добавляется радиус. Для этого придется переопределить методы инициализации, прорисовки и скрытия.

Type

TCircle = object(TPoint) R : Word;

Procedure Init(InitX, InitY, InitR:Word; InitC:Byte); Procedure Show;

Procedure Hide;

Procedure Done;

end;

Procedure TCircle.Init(InitX,InitY,InitR : Word; InitColor

:Byte); begin

inherited Init(InitX, InitY, InitC); R := InitR

end;

Procedure TCircle.Show; begin

Graph.SetColor(Clr); Graph.Circle(X, Y, R); Visib := True

end;

Procedure TCircle.Hide; begin

Graph.SetColor(Graph.GetBkColor); Graph.Circle(X, Y, R);

Visib := False end;

Procedure TCircle.Done; begin

inherited Done; R := 0

end;

Таким образом, мы получили два объекта, методы которых Show и Hide делают одно и то же, но разными способами (полиморфизм). Но если мы создадим экземпляр этого объекта, проинициализируем его, а затем попытаемся переместить вызовом метода MoveTo, кото- рый был унаследован, то переместится точка, а не окружность. Связано это с тем, что при компиляции в машинный код вместо вы- зова подпрограммы транслятор подставляет адрес точки входа в эту подпрограмму. Это же справедливо и для методов, поэтому при трансляции метода MoveTo объекта TPoint будут подставлены ад- реса точек входа методов Show и Hide объекта TPoint. Объект же

140

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]