referat_TP (664057), страница 3
Текст из файла (страница 3)
Ранее отмечалось, что программная реализация объекта представляет собой объединение данных и процедур их обработки. В Турбо Паскале имеется тип object, который можно считать обобщением структурного типа record. Переменные объектного типа называются экземплярами объекта. Здесь требуется уточнение – экземпляр лишь формально можно назвать переменной. Его описание даётся в предложении описания переменных, но в действительности экземпляр – нечто большее, чем обычная переменная.
В отличии от типа «запись», объектный тип содержит не только поля, описывающие данные, но также процедуры и функции, описания которых содержатся в описании объекта. Эти процедуры и функции называются методами. В описании объекта фактически содержатся лишь шаблоны обращений к методам, которые необходимы компилятору для проверки соответствия количества параметров и их типов при обращении к методам. Вот пример описания объекта:
type
Location = object
X, Y: Integer;
procedure Init (InitX, Inity: Integer);
function GetX: Integer;
function GetY: Integer;
end;
Здесь описывается объект, который может использоваться в дальнейшем, скажем, в графическом режиме и который предназначен для определения положения на экране произвольного графического элемента. Объект описывается с помощью зарезервированных слов object…end, между которыми находятся описания полей и методов. В нашем примере объект содержит два поля для хранения значений графических координат, а также описания процедуры и двух функций – это методы данного объекта. Процедура предназначена для задания первоначального положения объекта, а функции – для считывания его координат.
Зарезервированное слово private позволяет ограничить доступ к полям объекта. В следующем примере доступ к переменным X и Y возможен только через методы объектного типа Location:
type
Location = object
procedure Init (InitX, Inity: Integer);
function GetX: Integer;
function GetY: Integer;
private
X, Y: integer;
end;
В секции private могут находится и методы объекта.
Полное описание методов, то есть описание их реализации, должно находится после описания объекта. Имена методов составные и складываются из имени объекта и имени метода, разделённых точкой:
procedure Location. Init (InitX, Inity: Integer);
begin
X : = InitX;
Y : = InitY;
end;
fuction Location. GetX: Integer;
begin
GetX : = X;
end;
fuction Location. GetY: Integer;
begin
GetY : = Y;
end;
После того как объект описан, в программе можно использовать его экземпляры, то есть переменные указанного объектного типа:
var
GrMarket : Location;
2.1 Основные принципы ООП
Элементы объектно-ориентированного программирования появились в начале 70-х в языке моделирования Симула, затем получили своё развитие, и в настоящее время ООП принадлежит к числу ведущих технологий программирования. В Турбо Паскале поддержка этой технологии появилась, начиная с версии 5.5 (1989 год).
Основная цель ООП, как и большинства других подходов к программированию, - повышение эффективности разработки программ. Идеи ООП оказались плодотворными и нашли применение не только в языках программирования, но и в других областях Computer Science, например, в области разработки операционных систем.
Появление объектно-ориентированного программирования было связанно с тем наблюдением, что компьютерные программы представляют собой описание действий, выполняемых над различными объектами. В роли последних могут выступать, например, графические объекты, записи в базах данных или совокупности числовых значений. В традиционных методах программирования изменение данных или правил и методов их обработки часто приводило к необходимости значительного изменения программ. Всякое существенное изменение программы – это большая неприятность для программиста, так как при этом увеличивается вероятность ошибок, вследствие чего возрастает время, необходимое для «доводки» программы. Использование ООП позволяет выйти из такой ситуации с минимальными потерями, сводя необходимую модификацию программы к её расширению и дополнению. Сразу замечу, что ООП не является панацеей от всех программистских бед, но его ценность как передовой технологии программирования несомненна. Изучение идей и методов объектно-ориентированного программирования – не очень простая задача, однако освоение ООП может существенно упростить разработку и отладку сложных программ.
Мы уже привыкли использовать в своих программах процедуры и функции для программирования тех сложных действий по обработке данных, которые приходится выполнять многократно. Использование подпрограмм в своё время было важным шагом на пути к увеличению эффективности программирования. Подпрограмма может иметь формальные параметры, которые при обращении к ней заменяются фактическими параметрами. В этом случае есть опасность вызова подпрограммы с неправильными данными, что может привести к сбою программы и её аварийному завершению при выполнении. Поэтому естественным обобщением традиционного подхода к программированию является объединение данных и подпрограмм (процедур и функций), предназначенных для их обработки.
2.2 Инкапсуляция
В Турбо Паскале средства объектно-ориентированного программирования связаны с тремя зарезервированными словами: OBJECT CONSTRUCTOR и DESTRUCTOR и двумя стандартными директивами: PRIVATE и VIRTUAL.
Зарезервированное слово OBJECT используется для описания объекта. Описание объекта должно помещаться в разделе описания типов, например:
type
Tpoint = object
X,Y: Integer; {Координаты точки}
Color:word; {Цвет точки)
Visible: Boolean; {Признак светимости}
Procedure Setlocation (NewX, NewY: integer);
{Задает новое положение, точки на экране}
Procedure SetCoforfNewColor: word); {Устанавливает цвет точки}
Procedure SetVislble(VIS: Boolean);
{Выводит или гасит точку)
Procedure GetLocatIon(var Xloc, YLoc:integer);
{Возвращает координаты точки}
Function GetColor: word;
{Возвращает цвет точки)
Function GetVislble: Boolean;
{Возвращает признак светимости точки}
end; {Конец описания объекта ТРOINT)
В этом примере описывается объект TPOINT, представляющий собой данные и методы (процедуры и функции), необходимые для работы с графическими точками на экране ПК. Заметим, что инкапсулированные объект процедуры и функции называются методами. Как видим, каждая точка характеризуется некоторым набором данных (своими координатами X и У, цветом COLOR и признаком светимости VISIBLE). Над этими данными определены все необходимые алгоритмические действия. С помощью этих переменных можно осуществлять все предусмотренные, в объекте действия, например, для переменных типа TPOINT можно высветить или погасим, любую точку, переместить ее по экрану, изменить цвет.
Нетрудно заметить, что описание объекта и использование объектных переменных во многом похоже на описание и использование записей: инкапсулированные в объекте данные и методы становятся доступны с помощью оператора присоединения WITH или с помощью составных
имен, например:
if Point.GetVisible then Polnt.SetVisible(False);
При описании объекта вначале, описываются все инкапсулированные в нем данные, а затем - методы доступа к этим данным. В качестве методов используются процедуры и функции, а также конструкторы и деструкторы.
Таким образом, указание методов при описании объекта подобно их опережающему описанию. Поскольку данные и методы инкапсулированы в одном объекте, все данные автоматически становятся глобальными, по отношению к любым методам и могут использоваться в них произвольным образом. Точнее говоря, любой метод объекта работает с невидимым оператором WITH, обеспечивающим ему доступ ко всем полям (как мы увидим далее, поля могут следовать в объявлении типа и после объявления метода и в этом смысле не являться для него глобальными). При обращении к методу ему передается особый идентификатор SELF, представляющий собой обобщенное имя экземпляра объекта. Любой метод может использовать идентификатор SELF, чтобы явно указать на принадлежащий объекту метод или поле. Например:
type ТСоо = record
X.Y: integer;
end;
TPoint = object
X,Y: integer;
Procedure lnit(Coo: TCoo);
end;
Procedure TPofntfCoo: TCoo):
begin
with Coo do
begin
Self.X := X;
Self.Y := Y;
end;
end;
2.3 Наследование
Любой объект может быть объявлен потомком ранее описанного объекта. В этом случае он наследует все данные и методы объекта-родителя и может дополнять их своими данными и методами. При объявлении объекта-потомка за словом OBJECT в круглых скобках указывается имя объекта-родителя. У объекта может быть сколько угодно потомков, но только один родитель. При объявлении объекта-потомка TUNE перечислены лишь те данные и методы, которых недостает в объекте-родителе TPOINT, остальные TLINE автоматически наследует от своего родителя.
Таким образом, описание объекта-потомка TLINE эквивалентно такому описанию объекта TLINE_ANOTHER:
type
TLine_Another = object
X, Y Integer; {Координаты начала линии}
Color word; {Цвет линии)
Visible Boolean; (Признак светимости)
XE.YE: Integer; {Координаты второго конца)
Procedure SetLocation(NewX, NewY: integer);
{Задает новое положение начала линии)
Procedure SetColor(NewColor: word);
{Устанавливает цвет линии)
Procedure SetVIsible(Vis: Boolean);
{Выводит или гасит линию}
Procedure GetLocation(var XLoc, YLoc: integer);
{Возвращает координаты начала линии}
Function GetColor: word;
{возвращает цвет линии}
Function GetVisible: Boolean;
{Возвращает признак светимости линии}
Procedure SetLIneLocationfxl.X1,Y1,x2 ,y2: integer);
{Задает новое положение линии на экране}
Procedure GetLineLocatlon(var x11,y1l,x2l,y2l):integer);
{Возвращает координаты линии}
Procedure SetLineVJsible(vis: Boolean);
{Выводит или гасит линию)}
end; {Конец описания объекта TLIne_Another}
Из этого примера видно главное преимущество наследования: при описании объекта-потомка вам нет необходимости заново описывать уж существующие в объекте-родителе поля и методы. Потомок просто использует их нужным образом для реализации требуемых от него действий все, в чем нуждается потомок, это описать специфичные для него поля методы, недостающие в объекте-родителе.
Наследование распространяется на любые объекты, в том числе и объекты-потомки: если в качестве родителя указано имя объекта, который сам по себе является потомком, новый объект наследует все свойства своего родителя и все свойства своих прародителей. Таким образом, наследование обеспечивает создание дерева родственных объектов.
Как и любое другое дерево, дерево объектов имеет «корень» объект являющийся прародителем всех других объектов иерархии, и «ветви» порожденные от него потомки. По мере передвижения от корня к ветвям и перехода с ветви на ветвь объекты разрастаются в своих размерах, присоединяя к себе все новые и новые поля и методы. Если иерархия объектов хорошо продумана, на каждом ее уровне к объекту-родителю добавляются только необходимые поля и методы, поэтому в таком разрастании на самом деле нет ничего плохого. Более того, компоновщик Турбо Паскаля тщательно проверит откомпилированную программу и удалит из нее все лишнее - в том числе в исполняемую программу (ЕХЕ-файл) не будут включены методы, которые по каким-либо причинам не используются в программе.
Механизм наследования это, пожалуй, самое мощное свойство ООП. Без наследования объекты превращаются в простую комбинацию данных и подпрограмм, не дающую качественных преимуществ по сравнению с традиционными для Паскаля процедурами и модулями. Наоборот, механизм наследования позволяет строить библиотеку по принципу «от простого - к сложному». Вводя с помощью наследования новый объект в свою библиотеку, программист в максимальной степени использует уже созданные (и, возможно, отлаженные) ранее объекты. Такой принцип конструирования программ называется восходящим программированием. В отличие от нисходящего программирования, он не дает возможности поэтапного создания программы. Мелкие детали реализации объектов заслоняют собою генеральный алгоритм, поэтому при использовании ООП рекомендуется сочетание подходов: методами нисходящего программирования генеральный алгоритм расчленяется на ряд относительно крупных и законченных в смысловом отношении фрагментов (модулей), а реализация этих фрагментов может основываться на объектно-ориентированном программировании.
2.4 Полиморфизм
Объект-потомок может не только дополнять поля и методы родителя, но и заменять методы родителя на новые (заменять поля родителя нельзя!). Например, вместо правила SETLINEVISIBLE мы могли бы в объекте TLINE объявить правило SETVISIBLE, которое в этом случае перекроет (заменит собой) одноименное правило объекта-родителя TPOINT. В результате, к разным родственным объектам TPOINT и TUNE можно было бы применять одноименные правила SETVISIBLE, обеспечивающие сходные в смысловом отношении действия - показать или сделать невидимым графический объект. Свойства, позволяющее называть разные алгоритмические действия одним именем, называется полиморфизмом.