Основы программирования (947332), страница 61
Текст из файла (страница 61)
Метод Error объявляемвиртуальным, так как он вызывается из другого метода класса и будет переопределяться в классах потомках, в то время как метод, из которого он вызывается, скорее всего переопределяться не будет (1-й случай обязательного использования позднего связывания).Unit Input;InterfaceUses crt, Win;Type TInput=-Object(TWin)inp:TWin; {окно ввода}Constructor Init(axl,ayl,ax2,ay2,aattr,axt,ayt:integer;atext:str80;bxlybylybx2yby2ybattrybxtybyt:integer;btext:str80);procedure Draw; {вывод окна}procedure Clear; {очистка поля ввода}36812. Разработка библиотеки интерфейсных компонентовprocedure Input;(ввод строки из окна}function Error:boolean; virtual; {проверка введенных данных}end;ImplementationConstructor TInputJnit;Begininherited Init(axl, ay I, ax2, ay2, aattr, axt, ayt, atext);Inp.Init(bxI, by J, bx2, by2, battr, bxt, byU ');end;Procedure TInput.Draw;Begininherited Draw;inp.Draw;End;Procedure TInput.
Clear;Begininp.text:-**;inp.Draw;End;Procedure TInput.Input;BeginWindow (inp.xl, inp.yl, inp.x2, inp.y2);TextBackGround(inpMttr div 16);TextColorfinp.attr mod 16);repeatGotoxy(inp.xt, inp.yt);Clear;ReadLnfinp, text);Gotoxyfinp.xt, inp.yt);Write(inp.text);until not Error;end;Function TInput.Error; {проверка не выполняется}beginError: "^false;end;EndК л а с с T M e s s a g e описываем в модуле Message.Unit Message;InterfaceUses crty Win;369Часть 2. Объектно-ориентированное программированиеТуре TMessage='Object(TWin)ok:TWm;{окно подтверждения}procedure Init(axl, ayj, ах2, ау2, aattr, cat, ayt: integer;atext:str80;bxl, by], bx2, by2, battn bxt, byt:integer;btext:str80);procedure Run;{ожидание подтверждения}procedure Draw; {вывести окно}end;ImplementationProcedure TMessage.Init;Begininherited Initfaxl, ayl, ax2, ay2, aattr, cat, ayt, atext);ok.
Initfbxl, by], bx2, by2, battr, bxt, byt, btext);end;Procedure TMessage.Draw;Begininherited Draw; {выводим родительское окно}okDraw; {выводим окно запроса на продолжение работы}End;Procedure TMessage.Run;BeginDraw;{выводим окно}ReadKey; {ожидаем подтверждения}.End;End.К л а с с T M e n u описываем в модуле Menu. Инициализацию объектных полей-массивов целесообразно выполнять типизированными константами.
Несовпадения размерности массивов, если используются не все пунктыменю, можно избежать, описав параметры как открытые массивы, не забыв,что индекс элементов открытого массива начинается с нуля.Unit Menu;InterfaceUses crt, Win;Type TMenu'=^Object(TWin)nalt:integer;{количество альтернатив в меню}masalt:array[L.10] ofTWin; {массив альтернатив меню}npos'.integer;{номер выбранной альтернативы}constructor Initfaxl,ayl ,ах2,ау2,aattr,axt, ayt: integer; atext:str80;n: integer;const w:array ofTWin); {открытый массив TWin}procedure Run;{реализация работы с меню}procedure Draw; virtual; {вывести окно}37012.
Разработка библиотеки интерфейсных компонентовprocedure Enter; virtual; {при нажатии на Enter ...}end;ImplementationConstructor TMenu.Init;Var i: integer;Begininherited Init(axl, ay I, ax2, ау2, aattr, axt, ayt, atext);nalt:=n; {количество реально используемых пунктов меню}for i:=I to nalt domasalt[i]Jnit(w[i-l],xly wfi-IJ.yl, wfi'lj.x2, w[i-lj.y2,wfi'ljMttr, wfi'JJ.xt, wfi'IJ.yt, wfi-lj.text);End;Procedure TMenu.Draw;Var i:integer;Begin { очищаем экран}TextBackGround(O);TextColor(l);Windowd 1M25);Clrscr;inherited Draw;{выводим основное окно}for i;=l to nalt do masaltfiJ.Draw; {выводим окна пунктов}End;Procedure TMenu.Run;Var chl,ch2;char;temp: integer;BeginDraw;npos:=nalt;masalt[npos].Setattr(71);repeatchl:=Readkey; {читаем код клавиши}ifchl =#0 then ch2: =Readkey;case chl of#0: case ch2 of#75:begin{перемещение курсора влево}temp:'=npoS'l;iftemp^O then temp:=nalt;{закольцовываем}masaltfnposJ.SetattrfJJ3);{убираем выделение}masaltftempfSetattr(71);{выделяем пункт}npos:=temp;end;#77:begin{перемещение курсора вправо}temp:=npos+I;iftemp=nalt+J then temp:=l; {закольцовываем}371Часть 2.
Объектио-ориентироваииое программированиеmasalt[npos].Setattr(113); {убираем выделение}masalt[temp].Setattr(71); {выделяем пункт}npos:=temp;end;end;#13: beginmasalt[npos].Setattr(113); {убираем выделение}Enter; {при нажатии Enter - выполняем пункт}Draw; {выводим главное меню}masalt[npos].Setattr(71); {выделяем пункт меню}end;enduntil((npos=nalt)and(chl=#13))or(chl=#27);{jxo завершения работы}End;Procedure TMenu.Enter; {абстрактный метод выполнения пунктов}Begin end;End.К л а с с T F o r m описываем в модуле Form. Инициализацию объектных полей - окон ввода также будем выполнять с использованием типизированных констант.Unit Form;InterfaceUses crt, WinJnputMenu;Type TForm=Object(TMenu)ninput:integer; {количество полей ввода}masinp:array[1..5] ofTInput; {массив полей ввода}constructor Initfaxl, ayl, ax2, ay2, aattr, axt, ayt: integer;atext:str80;n:integer; const wl:array of TWin;k:integer;const w2:array of TInput);procedure Draw; virtual; {вывод окна}procedure Clear; {очистка окон ввода}procedure Input; {ввод информации из окон ввода}end;ImplementationConstructor TForm.
Init;Var i: integer;Begininherited Init (ax 1, ayl,ax2, ay2, aattr, axt, ayt, atext, n, wl);ninput: =k; {количество задействованных окон ввода}37212. Разработка библиотеки интерфейсных компонентовfor i:-l to ninput domasmpfiJJnit(w2fi'JJ.xJ, w2fi'IJ.yI,w2fi'lj,x2, w2[i'l].y2, w2[i'l],attr,w2[i-l],xt, w2[i],yt,w2[i'l]Jext,w2[i'l]Anp.xl, w2[i'l]Anp.yl,w2[i-l].inp.x2, w2fi'JJJnp.y2,w2[i-l],inp.attn w2[i'l]Anp.xU w2[hl].inp.yt,w2fhlj, inp, text);End;Procedure TForm.Draw;Var i: integer;Begininherited Draw;{выводим основное окно}for i:=l to nalt do masalt[i].Draw; {выводим окна пунктов}for i:=l to ninput do masinpfiJ.Draw; {выводим окна ввода}End;Procedure TForm. Clear;Var i:integer;Beginfor i:=I to ninput do masinpfi],Clear; {чистим окна ввода}End;Procedure TForm.Input;Var i: integer;BeginClear;for i:=I to ninput do mas inp[iJ, Input; {вводим данные}End;End12.4. Создание программы с использованием библиотекиинтерфейсных компонентовВ параграфе 12.1 для программы «Записная книжка» уже была выполнена декомпозиция интерфейсной части предметной области (рис.
12.7). Осталось учесть взаимодействие профаммы с файлом: открытие, запись информации и ее поиск. Будем считать, что все эти действия выполняет объектФайл. Этот объект должен обрабатывать сообщения: Открыть/создать, Добавить и Найти. На рис. 12.11 показан результат объектной декомпозиции всейпредметной области профаммы.Проектирование и реализация объекта Файл.
Для реализации объекта Файл разработаем класс XBase (рис. 12.12).373Часть 2. Объектно-ориентированное программированиеГлавноеменюАктивизировать.--^^""^^-^^^^^АктивизироватьАктивизировать^--.^^^\Вводимени файлаДобавлениезаписейПоискзаписейНайти/^ДобавитьОткрыть/соз дать ^^^-«.^.^^^ГгАктивизировать\ж^1Файл\Сообщение оботсутствии^данных^Рис. 12.11.
Диаграмма объектов предметной области программыЭтот класс должен хранить файловую переменную f, через которую будет осуществляться доступ к файлу.Для поиска данных класс будет включать поля исходных данных поиска: p_family ~ фамилия и ропате - имя, ключи kl, к2, которые устанавливаются в зависимости от того, заданы или нет фамилия или имя и поля результатов поиска family, name, telefon. Кроме того, класс должен включать методоткрытия существующего или создания нового файла Open, метод добавления записей Add, метод поиска первой подходящей записи Find и метод поиска следующих подходящих записей FindNext.Наибольший интерес представляют функции поиска информации, которые в соответствии с заданием должны обеспечивать поиск по неполнымданным.
При этом поля Фамилия и Имя могут быть заданы, а могут бытьпропущены, могут совпадать, а могут не совпадать. Всего возможно 2"* = 16вариантов. В пяти случаях результат поиска положителен (табл. 12.1), т.е. записи считаются удовлетворяющими заданным условиям. Эти случаи можнообъединить в одно логическое выражение:ff = (kl л к2 л кЗ л к4) v (к1л к2 л кЗ) v ( i l л к2 л к4),TBasef, family, name, telefon, p_family, p_name, kl, k2Init(), Open(), Add(), Find(), FindNext(),Closefi:)Рис. 12.12. Класс TBase374где л - соответствует логическому «и», а V - логическому«или».Именно это выражение изаложено в метод поиска дляопределения «подходящих»записей.12. Разработка библиотеки интерфейсных компонентовТ а б л и ц а 12.1ФамилияуказанаklДаДа1!ДаДаДаДаДаДаНетНетНетНетНетНетНетНетИмяуказанок2ДаДаДаДаНетНетНетНетДаДаДаДаНетНетНетНетФамилиясовпадаеткЗДаДаНетНетДаДаНетНетДаДаНетНетДаДаНетНетИмясовпадаетк4ДаНетДаНетДаНетДаНетДаНетДаНетДаНетДаНетРезультатпоискаfrДаНетНетНетДаДаНетНетДаНетДаНетНетНетНетНет1Ниже приведен текст модуля Base, содержащего описание данного класса.Unit Base;InterfaceType str30=string[30];rec=recordrfamily rname, rtelefon:str30;end;Type TBase=Objectffile ofrec;family name, telefon:str30; {результаты поиска}pjdmilypjiame:str30;{данные поиска}kly k2:boolean;{ключи поиска}procedure Open(fname:str30);{открытие/создание файла}procedure Add(afamilyaname,atelefon:str30); {добавление записей}function Find(afamilyaname:str30):boolean; {поиск первого}375Часть 2.
Объектно-ориентированное программированиеfunction FindNext:boolean;{поиск следующего}procedure Closef;{закрытие файла}End:ImplementationProcedure TBase.Open;BeginAssign(f,fname); {инициализация файловой переменной}{$ЧResetф:{$1-^} {открытие с проверкой существования}iflOResultoO then ReWrite(f): {создание файла}End;Procedure TBase.Add;Var r:rec;BeginSeek(f,FileSize(f)); {ycTSLueiBnnBeiQM файловый указатель наконец файла}r.rfamily:^afamily; {создаем запись}кгпате.'^апате;к rtelefon: =atelefon;Write(f,rJ;{выводим запись в файл}End;Function XBase.
Find;BeginClose(f);{закрываем файл}ReSetф;{открываем файл для чтения}pjdmily:=afamily;{сохраняем данные поиска}р_пате:=апате;kJ:=p_family<> "; {устанавливаем два ключа поиска}к2:=р_пате<> 'VFind:=FindNext;{ищем запись по ключам}End;Function TBase.FindNext;Var r:rec;кЗ, k4, ff:boolean; {ключи поиска и его результат}Beginff:^false; {ключ поиска «запись не найдена»}while not Eof(f) and notjfdobeginReader);k3:=pjamily=r,rfamily;{строим еще два ключа поиска}к4: =р_пате =г тате;37612. Разработка библиотеки интерфейсных компонентовif(kl and к2 and кЗ and к4) {выбираем записи}or (not kl and k2 and k4) or (kl and not k2 and кЗ) thenbeginffi'^true;{ключ поиска «запись найдена»}family:^r.rfamily; {копируем результаты поиска}пате :=к тате;telefon: =к rtelefon;endend;FindNext:=ff; {возвращаем ключ поиска}end;Procedure TBase.Closef;beginС1о8еф; {закрываем файл}end;End,Проектирование интерфейса с использованием библиотеки интергфейсных компонентов.