Использование объектных средств
Во-первых, не нужно путать объектное программирование и объектно-ориентированное программирование(ООП). Первое является лишь частью такого общего понятия как ООП. ООП базируется на таких понятиях как инкапсуляция, наследование и полиморфизм. В смысл всех этих слов вам вникать пока не нужно, поэтому вы можете сразу их забыть. В объектном программировании используется лишь понятие объекта. Что он из себя представляет? Подобно обыкновенной записи Record, объект содержит данные различных типов. Но в отличие от записи он может содержать процедуры и функции Паскаля для работы с полями объекта (эти функции и процедуры называют методами работы над объектом). Свойство объектов содержать и поля данных и подпрограммы их обработки называют инкапсуляцией. Надо учесть, что желательно запрещать доступ к полям данных кроме как через методы этого объекта (иначе это считается плохим тоном). Правда, есть исключения (т.к. это ограничение иногда может существенно сказаться на эффективности программы и замедлить ее), поэтому иногда открывают доступ к полям. Перепишем модуль из прошлого параграфа с использованием объектного программирования:
unit ATable;
interface {$N+} Type _Month = (jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec); _ind1 = _Month; _ind2 = integer; _elem = single; PTab = ^CTab; CTab = object public {общеоступные поля данных и методы объекта, они могут свободно вызываться программистом в его программах} constructor Init(Low1,High1:_Ind1; Low2,High2:_Ind2; x:_elem); destructor Done; virtual; function GetLow1:_ind1; function GetLow2:_ind2; function GetHigh1:_ind1; function GetHigh2:_ind2; procedure Get(i1:_ind1; i2:_ind2;x:_elem); procedure put(i1:_ind1; i2:_ind2;x:_elem); private {эта директива в описании объекта открывает секцию описания скрытых полей и методов. Перечисленные в этой секции элементы объекта "не видны" программисту,если этот объект он получил в рамках TPU-модуля. Скрываются те поля и методы к которым программист (в его же интересах!) не должен иметь непосредственного доступа. В нашем примере он не может произвольно менять значения индексов и указатель на массив, т.к. это может привести к печальным последствиям. Кроме этого пользователь не может сам вызвать служебную процедуру Failure} procedure failure(n:word); private l1, h1:_ind1; l2, h2:_ind2; size1, size2:word; p:pointer; end;
Implementation {$Q+,R-} uses crt; {подключаем библиотеку crt для пользования процедурой очистки экрана} type al = array[0..0] of _elem; {тип-массив для хранения строк массива} pal = ^al; {указатель на строку массива} apal = array[0..0] of pal; {тип массив для хранения указателей на строки массива} papal = ^apal; {указатель на apal, нужен в этой программе исключительно для приведения типов, см.ниже}
procedure CTab.Failure; {Обратите внимание, что при описании методов имя метода дополняется спереди именем объекта, т.е. используется составное имя метода. Кроме этого список аргументов передаваемых подпрограмме можно здесь опускать} begin ClrScr; {очистим экран, хотя надо ли это делать - вопрос весьма спорный, иногда надо видеть, что было на экране до того как программа выдала ошибку} writeln('Ошибка # ',n:1); {печатаем номер ошибки} case n of {расшифровываем код ошибки} 1:writeln('Недостаточно памяти для инициализации таблицы'); 2:writeln('Неверные границы'); 3:writeln('Неверные индексы при чтении'); 4:writeln('Неверные индексы при записи'); end; halt(1);{выходим мз программы} {можно улучшить эту процедуру, если она будет выводить метод объекта в котором возникла ошибка} end;
constructor CTab.Init; {Конструктор - это особый вид процедур. Конструкторы предназначены для создания конкретного экземпляра объекта. Объет может иметь достаточно много конструкторов, например, можно создать конструктор копирования объета. Конкретная задача конструктора - заполнение полей объекта данными} var k:longint; i,j:word; begin {проверим индексы на соответствие} if (Low1>High1) or (Low2>High2) then Failure(2); {заполняем поля объекта} l1:=Low1; h1:=High1; size1:=ord(h1)-ord(l1)+1; l2:=Low2; h2:=High2; size2:=ord(h2)-ord(l2)+1; {делаем стандартные проверки на вмещение массива в сегмент} k:=longint(size1)*Sizeof(pal); if (k>65520) or (k>MaxAvail) then Failure(1); GetMem(p,k); {выделяем память для массива указателей} k:=longint(size2)*Sizeof(_elem); if k>65520 then Failure(1); {выделяем память для size1 строк матрицы каждая размером, k-байт} for i:=0 to (size1-1) do begin if k>MaxAvail then Failure(1); GetMem(papal(p)^[i],k); end; {Заполняем матрицу элементом x} for i:=0 to (size1-1) do for j:=0 to (size2-1) do papal(p)^[i]^[j]:=x; end;
destructor CTab.Done; {Деструктор нужен для уничтожения экземпляра объекта, вся память которую взяли в конструкторе должна быт возвращена в деструкторе} var k:longint; i,j:word; begin {освобождаем память} k:=size2*Sizeof(_elem); for i:=0 to (size1-1) do FreeMem(papal(p)^[i],k); k:=Size1*Sizeof(pal); FreeMem(p,k); {следующие операторы не обязательны и введены для того, чтобы объект смог при вызове его методов выдать ошибку} p:=nil; size1:=0; size2:=0; l1:=_ind1(1); h1:=_ind1(0); l2:=_ind2(1); h2:=_ind2(0); end;
function CTab.GetLow1; {Функция возвращает нижнюю границу первого индекса} begin GetLow1:=l1; end;
function CTab.GetLow2; {Функция возвращает нижнюю границу второго индекса} begin GetLow2:=l2; end;
function CTab.GetHigh1; {Функция возвращает верхнюю границу первого индекса} begin GetHigh1:=h1; end;
function CTab.GetHigh2; {Функция возвращает верхнюю границу второго индекса} begin GetHigh2:=h2; end;
procedure CTab.Get; {Функция возвращает элемент} begin {Проверяем индексы на принадлежность матрице} if (i1<l1) or (i1>h1) or (i2<l2) or (i2<h2) then Failure(3); x:=papal(p)^[ord(i1)-ord(l1)]^[ord(i2)-ord(l2)]; {Т.к. p - нетипизированный указатель, то мы сначала приводим его к типу papal, а потом обращаемся к получившемуся оператору так, как будто это был бы указатель типа papal} end;
procedure CTab.Put; {Функция кладет элемент в матрицу} begin {Проверяем индексы на принадлежность матрице} if (i1<l1) or (i1>h1) or (i2<l2) or (i2<h2) then Failure(4); papal(p)^[ord(i1)-ord(l1)]^[ord(i2)-ord(l2)]:=x; end;
begin {часть инициализации пустая} end.
Популярное: Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение... Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... Почему стероиды повышают давление?: Основных причин три... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (418)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |