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

Программирование. Модуль GRAPH. Модульное и объектное программирование. Учебно-методическое пособие

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

41

Блок подпрограммы модуля, процедуры или функции имеет то же строение, что и у программы. То есть в ней могут быть локальные объекты и внутренние процедуры и функции.

Пример: модуль с процедурой и функцией.

Unit Modul; Interface

Procedure ISWAP(Var i, j: Integer); Function IMAX(i, j: Integer): Integer;

Implementation Procedure ISWAP; Var

t: Integer;

Begin

t:=i; i:=j; j:=t;

End;

Function IMAX: Integer; Begin

If i>j Then

IMAX:=i

Else

IMAX:=j;

End;

End.

2.4. Инициирующая часть модуля

Инициирующая часть завершает модуль. В ней может быть блок с операторами, содержащими некоторый фрагмент программы. Эти операторы выполняются до начала вызывающей программы и обычно используются для подготовки работы вызывающей программы. Например, в ней могут инициироваться (получать начальные значения) переменные, открываться требуемые файлы и т.д. Если этого не требуется, в инициирующей части обязателен только последний оператор End.

2.5. Компиляция и подключение модулей

Для того чтобы сформировать модуль (библиотеку) с подпрограммами, можно отладить подпрограммы в составе основной программы, а затем перенести их в модуль. Для использования подпрограмм модуля его надо оттранслировать, т.е. сформировать из Pas – файла TPU – файл на МД, подключить к среде директорию с TPU – файлами модулей и подключить сформированный модуль к основной программе с помощью оператора Uses.

В директории Options\Directories\EXE&TPU directory должно быть:

42

1)пустая строка, если TPU – файл надо поместить в текущий каталог;

2)имя директории, в которую необходимо записать сформированные TPU – файлы, если модуль должен в заданном каталоге.

Если TPU – файлы помещены не в текущем каталоге, то для их

использования в меню Options\Directories\EXE&TPU directory должна быть их директория.

Подключение модулей к вызывающей программе и их компиляция производится последовательности их перечисления в Uses. При переходе к очередному модулю система предварительно отыскивает все модули, на которые он ссылается. Ссылки модулей друг на друга могут иметь древовидную структуру. Но запрещается явное или косвенное обращение модуля к самому себе (его рекурсия).

43

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

Воснове того или иного языка программирования лежит некоторая руководящая идея, которая определяет стиль программ.

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

Для ее решения были разработаны строгие правила ведения проектов, которые получили название структурной методологии. В основе ее лежала идея структурирования программ, в соответствие с которой программист должен был решить, какие именно процедуры он будет использовать в своей программе и выбрать лучшие алгоритмы для реализации этих процедур. Использование идеи процедурного структурирования программ привело к созданию обширных библиотек программирования, содержащих множество сравнительно небольших процедур, из которых, как из кирпичиков можно, строить «здание программы».

По ходу прогресса в области вычислительной математики акцент в программировании стал смещаться с процедур в сторону организации данных. Оказалось, что это эффективная разработка сложных программ нуждается в контроле правильности использования данных. Логическим следствием развития этого направления стал модульный подход в разработке программ, характеризующийся стремлением «спрятать» данные и процедуры внутри модуля. Модуль – это автономно компилируемая программная единица, включающая в себя различные компоненты раздела описаний (типы, константы, переменные, процедуры и функции) и, возможно, некоторые инициирующие части программы. Это привело к созданию языков программирования, имеющих развитые структуры данных, среди которых: Алгол 60, позже Паскаль, Модуль-2, Си и множество других.

Начиная с языка Симул 67, в программировании наметился новый подход, который получил название объектно-ориентированного

44

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

ООП обладает мощным средством реализации задач программирования. В этом мы сможем убедиться при изучении библиотеки Turbo Vision, но, следует отметить, что все преимущества ООП в полной мере проявляются лишь при разработке достаточно сложных программ. Более того, инкапсуляция придает объектам совершенно особое свойство «самостоятельности», максимальной независимости от остальных частей программы.

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

3.1. Основные принципы объектно-ориентированного программирования

Объектно-ориентированное программирование основано на «трех китах» – трех основных принципах, придающих объектам новые свойства. Этими принципами являются:

инкапсуляция, наследование, полиморфизм.

Инкапсуляция – есть объединение в одно целое данных и алгоритмов обработки этих данных. В рамках ООП данные называют полями объекта, а алгоритмы – объектными методами.

Инкапсуляция позволяет в максимальной степени изолировать объект от внешнего окружения. Она существенно повышает надежность

45

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

Другим немаловажным следствием инкапсуляции является легкость обмена объектами, переноса их из одной программы в другую. Фактически ООП «провоцирует» разработку библиотек объектов, таких как Turbo

Vision.

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

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

Последовательное проведение в жизнь принципа «наследуй и изменяй» хорошо согласуется с поэтапным подходом к разработке крупных программных проектов и во многом стимулирует такой подход.

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

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

46

3.2.Создание объектов

ВТурбо Паскаль для создания объектов используются три зарезервированных слова: object, constructor, destructor и три стандартных директивы: private, public, virtual.

Зарезервированное слово object используется для описания объекта. Описание объекта должно помещаться в разделе описания типов:

Type

MyObject=Object {Поля объекта}

{Методы объекта}

End;

Если объект порождается от какого-либо родителя, то имя родителя указывается в круглых скобках сразу за словом object:

Type

MyDescendantObject=Object(MyObject)

End;

Любой объект может иметь сколь угодно потомков, но только одного родителя, что позволяет создавать иерархические деревья наследования объектов.

Пример: Создать объект, содержащий фамилию, имя, отчество человека.

Program DemoObject; Type

TPerson=Object

Family: String[20]; Name: String[15]; Father: String[25];

End; Var

MyPerson:TPerson; Begin

With MyPerson Do Read(Name);

Readln;

With MyPerson Do Writeln(Name);

Readln;

End.

47

Начинающие программисты достаточно часто используют оператор WITH для присвоения полям начальных значений. В рассмотренном примере действия With MyPerson Do read(Name) и with MyPerson Do Writeln(Name) будут, в общем-то, корректными, но не идеальными. Например, если в задаче часто приходится обращаться к объекту и делать сразу много записей, то естественным является создание процедуры ввода данных, а затем, как следствие, возникает соблазн создать процедуру вывода данных:

Procedure Vvod(Fm,Nm,Fth:String); Var

Family: String[20];

Name: String[15];

Father: String[25];

Begin

Family:=Fm;

Name:=Nm;

Father:=Fth;

End;

Procedure Vivod(Fm,Nm,Fth:String); Var

Family: String[20];

Name: String[15];

Father: String[25];

Begin

Fm:=Family;

Nm:=Name;

Fth:=Father;

End;

Однако возникает вопрос, почему при разработке процедур Vvod и Vivod специально для обслуживания типа Tperson необходимо снова указывать какой тип записи и какое поле его обрабатывает. Нет ли какогонибудь способа объединения типа записи в единое целое?

Такой способ имеется и называется методом.

Метод – это процедура или функция, включенная в объект таким образом, что экземпляр данного типа становится доступным для нее изнутри.

В определение типа включается только заголовок метода. При определении метода он дополнительно идентифицируется именем типа. Поля и методы являются двумя частями объекта.

Пример объекта предыдущей задачи с методами ввода и вывода.

Program DemoObject; Type

TPerson=Object

48

Family: String[20];

Name: String[15];

Father: String[25];

Procedure Vvod(Fm,Nm,Fth:String); Procedure Vivod(Fm,Nm,Fth:String); End;

Procedure Tperson.Vvod(Fm,Nm,Fth:String); Begin

Family:=Fm;

Name:=Nm;

Father:=Fth;

End;

Procedure TPerson.Vivod(Fm,Nm,Fth:String); Begin

Fm:=Family;

Nm:=Name;

Fth:=Father;

End;

Var

MyPerson: TPerson; afm,anm,afth:String;

Begin

Readln(afm);

Readln(anm);

Readln(afth);

MyPerson. Vvod(afm,anm,afth; Readln;

MyPerson. Vivod(afm,anm,afth; Writeln(anm);

Readln;

End.

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

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

Рассмотрим известную задачу создания управления объектом (птица, машущая крыльями).

Program DemoObgect Uses

Graph, CRT;

49

Type Ptica=Object;

x,y:Integer;

vver,pole,vnis:Pointer;

Mize,Size,Lize:Integer;

ch:Char;

Procedure Draw(xa,ya:Integer);

Procedure Mahi(bx,by:Integer);

Procedure Polet(ax,ay:Integer);

End;

Procedure Ptica.Draw(xa,ya:Integer); Begin

SetColor(14);

SetFillStyle(1,14);

FillEllipse(xa,ya,10,10);

Line(xa-10,ya,xa-30,ya);

Line(xa+10,ya,xa+30,ya);

Line(xa-30,ya,xa-50,ya-20);

Line(xa+30,ya,xa+50,ya-20); Size:=ImageSize(xa-50,ya-20,xa+50,ya+20); GetMem(vver,size); GetImage(xa-50,ya-20,xa+50,ya+20,vver^); ClearDevice:

FillEllipse(xa,ya,10,10);

Line(xa-10,ya,xa-30,ya);

Line(xa-10,ya,xa+30,ya); Line(xa-30,ya,xa-50,ya+20); Line(xa+30,ya,xa+50,ya+20); Lize:=ImageSize(xa-50,ya-20,xa+50,ya+20); GetMem(vniz,lize); GetImage(xa-50,ya-20,xa+50,ya+20,vniz^); ClearDevice:

End;

Procedure Ptica.Mahi(bx,by:Integer); Begin Mize:=ImageSize(bx,by,bx+100,by+40); GetMem(pole,mize); GetImage(bx,by,bx+100,by+40,pole^); PutImage(bx,by,vver^,1);

Delay(70);

PutImage(bx,by,pole^,0);

PutImage(bx,by,vniz^,1);

Delay(70);

50

PutImage(bx,by,pole^,0);

End;

Procedure Ptica.Polet(ax,ay:Integer); Begin

Repeat

If KeyPressed Then Begin

ch:=ReadKey; Case ch Of

#77:ax:=ax+10; #75:ax:=ax-10; #80:ay:=ay+10; #72:ay:=ay-10;

End;

Mahi(ax,ay);

End

Else Mahi(ax,ay);

Until ch=#32; End;

Var

GrDriver, GrMode,alx,aly:Integer; gol:Ptica;

Begin GrDriver:= Detect;

InitGraph (GrDriver, GrMode, 'C: \Bp\BGI'); Readln;

Gol.Draw(100,100);

Gol.Polet(100,100);

Readln;

CloseGraph;

End.

3.3. Наследование, правила наследования

Факт наследования каким-либо объектом характеристик родительского объекта обозначается указанием после ключевого слова Object имени непосредственного родителя, которое заключается в круглые скобки.

Этот объект по сравнению со своим родительским объектом может быть расширен как новыми информационными полями, так и новыми методами.

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

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