- •1. Библиотечный модуль Graf
- •1.1. Характеристика графических режимов работы адаптера
- •1.2. Основные процедуры и функции графического модуля
- •Процедура CloseGraph
- •1.3. Изображение линий и точек
- •1.4. Изображение многоугольников
- •1.5. Изображение дуг, окружностей, эллипсов
- •1.6. Краски, Палитры, Заполнения
- •Процедура GetDefaultPalette
- •Процедура SetFillStyle
- •1.7. Вывод текста
- •Задает выравнивание выводимого по отношению к текущему положению указателя или к заданным координатам. Заголовок:
- •Процедура SetUserCharSize
- •Функция TextWidth
- •Функция TextHeight
- •1.8. Координаты. Окна. Страницы
- •Функции GetX и GetY
- •Процедура SetViewPort
- •Процедура SetActivePage
- •1.9. Сохранение и выдача изображений
- •2. Объектно-ориентированное программирование
- •2.1. Основные принципы ооп
- •2.2. Создание объектов
- •2.3. Наследование. Правила наследования
- •2.4. Виртуальные и динамические методы
- •2.5. Отличие виртуальных и динамических методов
- •2.6. Деструкторы
- •Список заданий выпускной квалификационной работы
- •Литература
2.1. Основные принципы ооп
Объектно-ориентированное программирование основано на «трех китах» – трех основных принципах, придающих объектам новые свойства. Этими принципами являются:
инкапсуляция,
наследование,
полиморфизм.
Инкапсуляция – есть объединение в одно целое данных и алгоритмов обработки этих данных. В рамках ООП данные называют полями объекта, а алгоритмы – объектными методами.
Инкапсуляция позволяет в максимальной степени изолировать объект от внешнего окружения. Она существенно повышает надежность разрабатываемых программ, поскольку локализованные в объекте алгоритмы обмениваются с программой сравнительно небольшими объемами данных, причем количество этих данных и их тип обычно жестко контролируются. В результате замена или модификация алгоритмов и данных, инкапсулированных в объект, как правило, не влечет за собой серьезных последствий для программы в целом (в целях повышения защищенности программ в ООП почти не используются глобальные переменные).
Другим немаловажным следствием инкапсуляции является легкость обмена объектами, переноса их из одной программы в другую. Фактически ООП «провоцирует» разработку библиотек объектов, таких как Turbo Vision.
Наследование –это свойство объектов порождать своих потомков. Объект-потомок автоматически наследует от родителя все поля и методы, может дополнять объекты новыми полями и заменять (перекрывать) методы родителя или дополнять их.
Принцип наследования решает проблему модификацию свойств объекта и придает ООП в целом исключительную гибкость. При работе с объектами программист обычно подбирает объект, наиболее близкий по своим свойствам для решения конкретной задачи, и создает от него одного или нескольких потомков, которые «умеют» делать то, что не реализовано в родителе.
Последовательное проведение в жизнь принципа «наследуй и изменяй» хорошо согласуется с поэтапным подходом к разработке крупных программных проектов и во многом стимулирует такой подход.
Полиморфизм –это свойство родственных объектов (т.е. объектов, имеющих одного общего родителя) решать схожие по смыслу проблемы разными способами. В ООП поведенческие свойства объекта определяются набором входящих в него методов. Изменяя алгоритм того или иного метода в потомках объекта, программист может придавать этим потомкам отсутствующие у родителя специфические свойства. Для изменения метода необходимо перекрыть его в потомке, т.е. объявит в потомке одноименный метод, и реализовать в нем нужные действия. В результате в объекте-родителе и объекте-потомке будут действовать два одноименных метода, имеющие разную алгоритмическую основу и, следовательно, придающие объектам разные свойства. Это и называется полиморфизмом объектов.
В Турбо Паскаль полиморфизм достигается не только описанным выше механизмом наследования и перекрытия методов родителя, но и их виртуализацией, позволяющей родительским методам обращаться к методам потомков.
2.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.
Начинающие программисты достаточно часто используют оператор WITH для присвоения полям начальных значений. В рассмотренном примере действия With MyPerson do read(Name) и with MyPerson do writeln(Name) будут, в общем-то, корректными, но не идеальными. Например, если в задаче часто приходится обращаться к объекту и делать сразу много записей, то естественным является создание процедуры ввода данных, а затем, как следствие, возникает соблазн создать процедуру вывода данных:
Procedure Vvod(Fm,Nm,Fth:string);
Family: String[20];
Name: String[15];
Father: String[25];
begin
Family:=Fm;
Name:=Nm;
Father:=Fth;
end;
Procedure Vivod(Fm,Nm,Fth:string);
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
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;
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);
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.
