Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие по Паскалю 3.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
313.34 Кб
Скачать

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.