№2 зертханалық жұмыста негізгі пішіннің жобасы мен модульінің бағдарламалық коды қарастырылады; Delphi ортасы пішінге құрауышты қосқан кезде оның бағдарламалық кодын автоматты түрде қосады, «оқиға» деген түсінік кіргізіледі және оның оқиғаны өңдеу прцедурасының көмегімен қалай өңделетіні көрсетіледі.
Тапсырма 1. №1зертханалық жұмыста құрылған жобаны іске қосу және жоба мен модульдің бағдарламалық кодын көру.
Delphi – ді іске қосыңыз.
Негізгі менюдің командасын орындаңыз: File \ Open Project
Ашылған терезенің жобалар тізімінен (.DPR кеңейткіші бар файлдар) TEST.DPR аты бар жобаны тауып алыңыздар, оған тышқанның сол жағымен бір рет шертіп, ОК - ді таңдаңыз немесе пернетақтадан Enter пернесіне басыңыз.
Экранда «Программа «Тест»» тақырыбымен пішін пайда болады.
Жобаның бағдарламалық кодын көру үшін негізгі менюдің Project\View Source командасын орындаңыздар.
Көңіл қойып жобаның бағдарламалық кодын қараңыздар (Сурет 1.8).
Сурет. 1.8. Жобаның бағдарламалық коды
Жобаның бағдарламалық коды бағдарламаның тақырыбынан, модульді қосу бөлімінен, компилятор директивасынан және бағдарламаның негізгі денесінен тұрады.
Бағдарламаның тақырыбы Program қызметші сөзінен тұрады, одан кейін жобаның атымен сәйкес келетін бағдарламаның аты орналасады. Жобаның аты оны сақтар кезде беріледі және ол Delphi ортасында орындалатын файлдың атын анықтайды.
Модульді қосу бөлімі Forms жүйелік модульі мен Mainform модульінен тұрады, олардың бағдарламалық коды Mainform.pas. файлында жазылады.
Компилятор директивасы {$R *.RES} бағдарламалық файлдың орындалуы үшін берілгендерден тұратын (мысалы, қосымшаның пиктограммасын сипаттау) файлдық ресурсты жүктеу үшін тағайындалады. Жұлдызша белгісінің тұруы ресурс файлының аты жоба файлының атымен дәл келеді, бірақ кеңейткіші .res болатындығын білдіреді.
Бағдарлама денесі begin сөзінен басталады және end сөзінен аяқталады. Ол үш жолдан тұрады: бірінші жол қосымшаны инициализациялау үшін, ал екінші жол Form1 негізгі пішінді құру және оны Application қосымшасының құрамына қосу, ал соңғы үшінші жол - қосымшаны іске қосу үшін тағайындалған.
Mainform модульінің бағдарламалық кодын көріп шығыңыздар (сурет 1.9). Ол үшін құрал – саймандар панельінің View Unit (тізімнен модульді таңдау) батырмасына басыңыздар.
View Unit (модульдерді көру) терезесі пайда болады. ( Бұл терезені негізгі менюден View\Units… командасын орындау арқылы немесе Ctrl+F12 пернелерінің комбинациясын басу арқылы шақыруға болады.)
Тізімнен Mainform атын таңдап, OK батырмасына басыңыздар.
Модульдер Object Pascal бағдарламалық тілінде қарастырылған стандартты конструкциядан тұрады (бөлімдердің тізбегі мен аттары). Жалпы түрдегі модульдің құрылымы:
Unit < модульдің аты>;
interface
…
implementation
…
initialization
…
finalization
…
end.
Сурет 1.9 Модульдің бағдарламалық коды
Модульдің тақырыбы Unit қызметші сөзінен тұрады, ол сіздің алдыңызда модульдің бағдарламалық коды тұр дегенді білдіреді, одан кейін модульдің аты орналасқан. Модуль онымен негізгі бағдарлама немесе басқа модуль қолданылуы үшін құрылады (біздің жағдайда модуль TEST.DPR жобасына қосылған).
Модульдің бағдарламалық коды модульдің тақырыбы мен төрт бөлімнен тұрады: интерфейс, жүзеге асыру, инициализация және қорытынды бөлім.
Интерфейс бөлімі interfase сөзінен басталады. Бұл бөлімде негізгі бағдарламаға немесе басқа модульдерге қатынау мүмкіндігі бар модульдің барлық ауқымды объектілерін жариялау жатыр (типтер, тұрақтылар, айнымалылар және бағыныңқы бағдарлама) Ол мыналардан тұрады:
а) модульді қосу бөлімі, uses сөзінен басталады. Біз көріп отырғанымыздай біздің модульімізге бірнеше жүйелі модульдер қосылған, олардың әрқайсысы белгілі функцияны атқарады;
б) типтерді сипаттау бөлімі, type сөзінен басталады. Оның құрамында Delphi ортасында құрылған форма типін сипаттау жатыр (TForm1 класы). Бұл класс құрауыштар типтерінің тізімі мен қандай да бір оқиғаны өңдеу процедураларының сипатталуынан тұрады. Біздің класс мыналардан тұрады: TmenuItem типтес меню элементтері N1, N2, .... N8 , олардың екеуі негізгі менюдің «Тест» және «Помощь» элементтері, ал қалған алтауы меню командаларына сәйкес келеді: «Тестирование», «Результат», «----», «Выход», «О программе» және «Инструкция». Delphi құрауыштарды пішінге орналастырған кезде автоматы түрде осы элементтерді бағдарламалық кодқа қосады; процедураны сипаттау Procedure N5Click(Sender: Tobject);
в) ауқымды айнымалыларды жариялау бөлімі var сөзінен басталады.
Жүзеге асыру бөлімі implementation сөзінен басталады. Ол меню командасына тышқанмен шерту, қарым – қатынас терезесінің батырмасына басу, пернетақтадағы пернеге басу және т.б. оқиғаларды өңдеу процедурасының денесінен тұрады. Сонымен бірге программистің меншік процедурасы мен функциясының сипаттамасынан тұруы мүмкін, олар өз кезегінде оқиғаны өңдеу процедурасынан шақырылады.
Нақ осы жағдайда бұл бөлімде біз бір ғана процедурамен жұмыс істейміз:
procedure TForm1.N5Click(Sender: TObject);
begin
Close;
end;
Бұл процедура меню элементі «Выход» - қа тышқанмен шерту оқиғасын өңдейді.
Компилятор директивасы {$R *.DFM}, жүзеге асыру бөлімінің басында орналасады, ол компиляторға жүзеге асыру бөліміне модульдің атымен сәйкес келетін .dfm кеңейткіші бар файлда орналасқан пішіннің қасиетінің мәнін орнататын команданы қою туралы бұйрық береді.
Инициязациялау және қорытындылау бөлімдері міндетті емес.
Инициялизациялау бөлімі модульдің аяғында болады және міндетті емес. Егер ол бар болса, онда ол initialization сөзінен басталады немесе begin ... end оператор жақсаларымен аяқталады. Бұл бөлімнің операторлары негізгі бағдарламаның басқаруына дейін орындалады және оның жұмыс істеуіне дайындық ретінде қолданылады.
Қорытындылау бөлімі finalization сөзінен басталады және бағдарламаның аяқталуы кезінде орындалатын операторлардан тұрады.
Тест орындалуы үшін қосымшаның негізгі модульі «Tест» -тің бағдарламасына қажетті оқиғаларды өңдейтін процедуларды атап өтіңдер.
Біз жасап отырған қосымша өзіміз қосқан менюі бар негізгі пішіннен тұрады. «О программе» меню командасының көмегімен біз анықтама терезі ретінде тағы бір қосымша пішінді шақыруымыз керек. Дайын шаблонды біз New Items қарым – қатынас терезесінен таңдап аламыз, ол үшін құрал – саймандар панельінің New батырмасына басу керек.
Тапсырма 2. Aboutbox пішінінің шаблонының негізінде «О программе» (сурет 1.10.) терезесін құру.
File негізгі менюінен New пунктін таңдап алыңыз, осы пункттің ағымды менюінен Other... таңдаңыз, сонда New Items қарым - қатынас терезесі пайда болады, Forms вкладкасынан Aboutbox пішінін таңдаңыз.
Келесі элементтерден тұатын Aboutbox стандартты терезесі пайда болады:
графикалық сурет, ол пішінге Additional құрауыштар палитрасының Image (кескін) батырмасының көмегімен қойылады;
мәтіндік құрауыштар (TLabel);
ОК батырмасы.
Aboutbox пішінінің Объект Инспектірінің Caption қасиетіне О программе терезенің тақырыбын жазыңыздар.
Image құрауышына тышқанмен шерту арқылы активтеңіз.
Суреттің маңайында қара квадраттары бар жақтау пайда болады.
Жақтаудың қара кадраттарын тышқанмен ұстай отырып Image құрауышының шекарасын қойылатын графикалық объектінің шекарасына дейін өзгертіңіз.
Image құрауышының Объект Инспектірінің Picture қасиетінің үш нүктесі бар батырмасына шертіңіз.
Picture Editor (Сурет редакторы) терезесінің Load командасын орындаңыздар.
Load Picture терезесінің «Папка:» өрісінен 256color каталогқа өтіңіздер (C:\Program Files\Common Files\Borland Shared\Images\Splash).
Каталог файлының тізімінен SHIPPING.BMP таңдаңыз (қалауларыңа қарай басқасын таңдауға болады) және «Открыть» басыңыз.
Picture Editor терезесінің OK батырмасына басу арқылы суретті «О программе» пішінінің дайындалып жатқан жақтауына орналастырыңыздар.
Инспектор Объектісін Image құрауышына бейімдеңіз және Stretch (масштабтау) қасиетіне true параметрін қойыңыз.
Сурет жақтауға толығымен орналасады.
Сурет 1.10 «О программе» пішінінің терезесі
Пішіндегі барлық мәтіндік құрауыштарды ( TLabel) жойыңыздар. Ол үшін әрбір құрауышты тышқанмен шерту арқылы белгілеңіз және Delete батырмасына басыңыз.
Aboutbox пішініне Label құрауышын қосыңыз (Standart палитра құрауышынан ). Оған мәтінді кіргізесіздер.
Label1 құрауышы үшін Объект Инспекторінінің AutoSize қасиетіне false параметрін орнатыңыз (бұл қасиет Label - дің ұзындығын енгізілген мәтіннің ұзындығы бойынша алады). Alignment және Layout қасиеттеріне taCenter, tlCenter параметрлерін орнатыңыздар, ол мәтінді құрауыштың центрі бойынша орналастыруға қолданылады. WordWrap қасиетіне – True (сөзді буынға бөлуге рұқсат етіледі).
Caption қасиетіне Программа Тест © Copyrighte by Makeew S. деп жазыңыздар (өз фамилияңызды көрсетіңіз).
Тышқанның көмегімен Label1 құрауышына қажетті өлшемді беріңіз және оны терезенің оң жақ жоғарғы бұрышына орналастырыңыз.
Color қасиетіне фонның түсін орнатыңыз.
Font қасиетінің үш нүктесі бар батырмасына басу арқылы Қаріп қарым – қатынас терезесін шақырып, қаріптің түсін, өлшемін және түрін белгілеңіздер.
Әртүрлі қаріпі бар мәтінді енгізу үшін тізбекпен бірнеше Label қолданылады және әрбіреуі үшін өз қасиеті орналастырылады. Әрбір Label – ге 256 символ орналастырылады.
Пішіндегі ОК батырмасын активтеңіздер.
Объект Инспектірінің осы батырмасының Caption қасиетін Продолжить деп өзгертіңіздер.
Осы батырманың «О программе» терезесінде орналасуы мен өлшемін өздеріңіз белгілеңіздер.
Тапсырма 3. «О программе» пішінінің бағдарламалық модульін MainForm негізгі пішінінің модульіне қосу.
Ағымды терезе ретінде «Программа «Тест»» неізгі пішінінің терезесін алыңыздар (терезенің бос жеріне тышқанмен шерту арқылы немесе 1 – ші зертханалық жұмыста көрсетілген әдісті қолдану арқылы).
«Помощь» менюін ашыңыздар және «О программе» командасына тышқанмен шертіңіздер.
«О программе» меню командасына тышқанмен шерткенде өңделетін процедурасы бар редактор терезесінің бағдарлама коды ашылады.
Тышқанның көрсеткіші жанып - өшіп тұрған жерге мынаны жазыңыздар:
AboutBox.ShowModal;
Бұл команда бағдарламаның орындалуы барысында модальдық режимде экранға «О программе» терезесін шығарады.
Құрылған модульді сақтаңыздар: құрал – саймандар панельінің Save All батырмасына басыңыздар; модульді сақтау терезесінің «Имя файла» өрісіне about_x деп жазып, «Сохранить» батырмасына басыңыздар, ал жоба мен қалған модульдер автоматты түрде сақталады.
Toggle Form/Unit батырмасына тышқанмен шерту арқылы код редакторы терезесінен MAINFORM.PAS негізгі пішінінің модульінің кодын шақырыңыздар (пішіннің өзіне сәйкес бағдарламалық модульге ауыстырлып қосылуы және керісінше). Бағдарламаның мәтінінің uses модульді ауыстырып қосу бөліміне үтір арқылы about_x деп жазыңыздар.
Бағдарламаны орындаңыздар. «Tест» бағдарламасының менюіндегі «О программе» командасының жұмыс істеу қабілетін тексеріңіздер.
Бұл зертханалық жұмыста біз қосымша қарым – қатынас терезелерін құруды үйрендік, оқиғаларды өңдеу, модульдерді негізгі бағдарламаға қосу, пішіндерге құрауыштарды орналастыру ( мәтіндер, графикалық суреттер және т.б.), сонымен бірге бағдарламалық модульдердің және жоба файлдарының құрылымдарын қарастырдық.
Зертханалық жұмыс № 3 ««Тест» қосымшасын құру»
№3 – ші зертханалық жұмыста №1 – ші зертханалық жұмыста ұсынылған көлемдегі «Tест» қосымшасын құруды аяқтаймыз; «Тестирование» және «Результат» пішіндерін құру үрдістерін қарастырамыз; негізгі модульдің бағдарламалық кодында бағдарлама құрудың қарапайым әдістерін көрсетеміз.
Тапсырма 1. Жобаны іске қосу. «Тестирование» пішінін құру.
Алдыңғы зертханалық жұмыста құрылған (TEST.DPR) бағдарламасын іске қосыңыздар және оның жұмыс істеу қабілетін тексеріңіздер. Жұмыс бағдарламасынан Выход командасын таңдап, жобалау режіміне қайтып оралыңыздар.
Енді «Тестирование» пішінін құруға кірісеміз.
Біздің тест 3 – 4 варианттан тұратын жауабы бар 5 сұрақтан тұрсын. Бізге осы 5 сұрақ жауабымен сиятындай пішін керек. Бұл мақсатта бізге парақтар тобынан тұратын жазба кітапша түріндегі пішін қажет, әрбір парақ парақтың нөмірі бар бетбелгіден тұрады. Delphi ортасындағы мұндай пішін шаблон түрінде болады. Бұл пішінді біздің жобамызға қосамыз.
Құрал – саймандар панельінің New командасын орындаңыздар, New Items терезесінен Forms қалташасын таңдаңыз, одан кейін Tabbed pages пішінін таңдап (Tabbed Notebook Dialog – бетбелгісі бар диалогтық жазба кітапша), ОК батырмасына басыңыздар.
Пішінді оқып – үйреніңіздер. Ол бетбелгісі бар үш парақтан және үш басқару батырмаларынан тұрады. Пішіннің әрбір парағы жұмыс істеп тұрған бағдарламада сәйкес бетбелгіге тышқанмен шерткенде шақырылады. Қайта таңдалған пішіннен Cancel және Неlр батырмаларын жойыңыздар. Объект Инспектірінен құрауыштар тізімін ашыңыздар. Бұл құрауыштар тізімінде әрбір құрауыш объект ретінде көрсетілген. Тізім келесі объектілерден тұрады: PagesDlg пішіні, PageControl1 жазба кітапшасы, үш парақ TabSheet1, TabSheet2, TabSheet3, Panel1, Panel2 екі панельдері және ОКBtn батырмасы.
Пішінге тақырып және объектілерге қысқартылған ат тағайындаңыздар: PagesDlg – ды таңдаңыздар, Caption қасиетіне Тестирование деп жазыңыздар, Name қасиетіне — TestDlg және Enter – ді басыңыздар. Енді қарым – қатынас терезесі «Тестирование» деген тақырыптан және TestDlg аты бар объектіден тұрады, ол Инспектір Объектісінің тізімдерінен шақырылады. Color қасиетіне пішіннің түсін орнатыңыздар, мысалы сары.
Жазба кітапшасының парақтар санын беске дейін өзгертіңіздер (сәйкес тестің сұрақтар санына байланысты) және олардың бетбелгілеріне Вопрос1, Вопрос 2 және т. б. деп жазыңыздар. Ол үшін Инспектір объектісінен TabSheet1 таңдаңыздар және Caption қасиетіне Вопрос 1 және т.б. деп жазыңыздар.
Парақ қосу үшін парақтың өрісіне тышқанның оң жақ батырмасымен шертіңіз, сонда контекстік меню пайда болады, одан New Page – ді таңдаңыздар.
«Тестирование» пішініндегі барлық 5 бетбелгі бір жолға сиюы үшін, жазба кітапшасының TabWidth (бетбелгінің кеңдігі) қасиетінің мәнін орнатыңыздар. Width қасиетінің мәні болып жазба кітапшасының кеңдігі алынады.
Тапсырма 2. Графикалық элементі бар тестің бірінші сұрағын көркемдеу.
Біздің жазба кітапшамыздың әрбір парағына сұрақ пен оның жауаптарын орналастырайық. Бірінші парақтан бастайық. Сұрақтың мәтінін жақтаудың түрлі – түсті панельіне жазамыз. Ол үшін Panel және Label құрауыштарын қолданамыз.
Объект Инспектірінен PageControl1 – ді таңдаңыздар және ActivePage (актив парақ) қасиетінен TabSheet1 – ді таңдаңыздар.
Активті парақ жазықтығынан жақтаудағы панель түрінде мәтінді енгізетін орын дайындаңыздар. Ол үшін бірінші параққа құрауыштар палитрасынан Panel құрауышын қосыңыздар және оны тышқанның көмегімен парақтың жоғарғы бөлігіне дейін созыңыздар (сурет 1.11). Align қасиетіне - alClient мәнін беріңіздер.
Объект Инспектірінің Color қасиетіне тышқанды екі рет шерту арқылы түстер палитрасын шақырыңыздар және панельдің мысалы, жасыл түсін орнатыңыздар.
Caption қасиетінен Panel3 деген жазуды жойыңыздар.
Панельге картинадағы сияқты жақтау жасаңыздар. Ол үшін Bevelinner (ішкі фаска) қасиетіне Lowered (төмендетілген) мәнін Bevelouter (сыртқы фаска) қасиетіне —Raised (көтеріңкі) мәнін тағайындаңыздар.
Дайын панельге Label құрауышын қосыңыздар, оны панельдің кеңдігіне дейін созыңыздар және мәтіннің центр бойынша жазылуы үшін Label құрауышының Autosize қасиетіне False мәнін орнатыңыздар. Alignment қасиетіне — taCenter (көлденеңінен алғанда центрлеу), Layout қасиетіне – tlCenter мәнін (көлднеңінен – центрі бойынша туралау),
Word Wrap қасиетіне (сөзді бөлуге рұқсат етіледі) – True мәнін тағайындаңыздар.
Label1 құрауышының Caption қасиетіне “ Заставкой какого программного продукта является эта картинка?” деп жазыңыздар, Font қасиетіне тышқанмен екі рет шерту арқылы Шрифт терезесін шақырып, қаріптің түсін, түрін және өлшемін орнатыңыздар.
Сурет қою үшін панель аймағына Additional қасиетінен Image құрауышын қосыңыздар және қара жақтауға тышқанмен екі рет шерту арқылы суретті редакциялау үшін Picture Editor терезесін шақырыңыздар. Load батырмасының көмегімен осы терезеден файлды жүктеу терезесін шақырып, C:\Program Files\Common Files\Borland Shared\Images\Splash\16color каталогынан Athena.bmp файлын жүктеңіздер.
Суреттің Stretch қасиетіне true мәнін тағайындаңыздар.
Қозғалысты бағыттау пернелері мен Shift батырмасының комбинациясын қолдана отырып, құрауыштың өлшемін өзгертуге болады, ал Ctrl батырмасымен комбинациясы арқылы құрауышты пішіннің бойымен жылжытуға болады.
Сурет 1.11 «Тестирование» пішінінің терезесі
Қарым – қатынас парағына біз жауаптың бірнеше варианттарын орналастыруымыз керек, оның ішінен тестен өтуші дұрыс деген бір жауапты таңдауы қажет. Қатардан балама таңдау жасау үшін Standard палитрасының RadioGroup деген құрауышын қолданамыз, ол бірнеше радиобатырмаларды бір топқа біріктіреді. (Мұндай атау аналогия бойынша көптеген радиобағдарламалардың ішінен біреуін таңдағанда бір ғана батырма іске қосылатын радиоқабылдағыштың батырмаларына қолданылады.)
«Тестирование» пішінінің бірінші сұрағының парағына RadioGroup құрауышын қосыңыздар және оның Caption қасиетіне топтың тақырыбын Варианты ответов беріңіздер.
Items (элементтер) қасиетіне тышқанның екі шертуімен String List Editor (Жол тізімінің редакторы) терезесін шақырыңыздар.
Бұл редактордың бірінші жолына Delphi, екінші жолына — Windows 95, үшіншісіне — Microsoft Office 95 деп жазып, ОК батырмасына басыңыздар.(бірінші жауап дұрыс болады). Жауаптың әрбір варианты RadioGroup құрауыш панельінің радиобатырмаларының қарама – қарсы жағында орналасады.
Қарым – қатынас терезесінің екінші парағына бірінші парақтың дайын панельін көшіріңіздер. Ол үшін бірінші парақтың панельін тышқанмен шерту арқылы ерекшелеңіз және Edit (редакциялау) менюінің Сору (көшіру) командасын орындаңыздар. Екінші парақты активтеңіз және Edit менюінің Paste (қою) командасын орындаңыздар.
Өздіктеріңнен №2, №3, №4, №5 сұрақтардан тұратын жауабы бар тағы 4 парақ құрыңыздар.
Пішіннің құрылған «Тестирование» модульін Test_x.pas деген атпен сақтаңыздар.
Негізгі пішіннің бағдарламалық кодына жобаның негізгі менюінен «Тестирование» пішінін іске қосатын команданы енгізіңіздер. Ол үшін «Программа «Тест»» пішінінің Тест\Тестирование меню командасына тышқанмен шертіңіздер – сонда осы оқиғаны өңдейтін дайындалған бағдарламалық коды бар терезе пайда болады. Тышқанның көрсеткіші жанып - өшіп тұрған жерге мыныны жазыңыздар
TestDlg.Showmodal;
Uses бөліміне қосылған модульдің атын test_x енгізіңіздер;
Тапсырма 4. “Результат” пішінін құру және жобаны аяқтау.
Сурет 1.12 «Результат» пішінінің терезесі
New Items қарым – қатынас панельінен Dialogs қалташасын таңдаңыздар және онда Standard Dialog (стандарттық қарым – қатынас терезесі) пішінінің шаблонын таңдаңыздар. Пішінге «Результат» тақырыбын беріп, Name қасиетіне объектінің атын Resultdlg жазыңыздар (сурет 1.12).
Пішіндегі батырмалардың ішінен ОК батырмасын ғана қалтырыңыздар. Оны пішіннің төменгі жағының центріне орналастырыңыздар. Ол үшін пішіннің аймағында тышқанның оң жақ батырмасымен батырмаға шертіңіздер. Пайда болған контекстік менюден Align командасын таңдап, пайда болған қарым – қатынас терезесінен Center in window параметрін таңдаңыздар.
Пішіннің панельінің жоғарғы жағына Label құрауышын қосыңыздар, оның Autosize қасиетіне false мәнін, ал Alignment қасиетіне— taCenter мәнін орнатыңыздар. Қаріптің атрибуттарын орнатыңыздар. Label құрауышының хабарламасы жобаның негізгі модульінің бағдарламалық кодына енгізіледі және хабарламаның мәтіні тестің нәтижесіне байланысты болады.
Пішінге сурет қойыңыздар.
Пішіннің файлын Result_x атымен сақтаңыздар және оны MainForm.pas модуліне қосыңыздар.
Тестен өткенде жауаптарды өңдейтін бағдарламалық кодты құрыңыздар. Негізгі пішіннің Тест\Результат меню командасына шерту арқылы Mainform модульінің кодын шақырыңыздар және тышқанның көрсеткіші жанып - өшіп тұрған жерге пернетақтаның көмегімен бағдарламаның мәтінін енгізіңіздер (көп нүктенің орнына дұрыс жауаптарының нөмірін ескере отырып, қалған 4 сұрақтың бағдарламасының жолын жазу керек.).
Mainform модулінің соңғы бағдарламалық коды
var ball:byte;
begin
ball:=0;
if TestDlg.RadioGroup1.ItemIndex=0 then ball:=ball+1;
if TestDlg.RadioGroup2.ItemIndex=
...
...
ResultDlg.Label1.Caption:=’Ваш результат:’+IntToStr(Ball);
ResultDlg.ShowModal;
end;
Тестілеу нәтижесінде әрбір дұрыс жауап 1 балл деп есептелінеді және балдардың жалпы қосындысы, максимум 5 жағдайында, Результат пішініне шығуы керек. Көрнекілік бағдарламалау құралдарының көмегімен бұл есепті шешу мүмкін емес, сондықтан қарапайым бағдарламалауға көшейік.
procedure TForm1.N6Click(Sender: TObject);
процедурасы тестілеу нәтижесінің балдарын қосады және нәтижені ball айнымалысына орналастырады. Тестен өтуші дұрыс жауабы бар радиобатырмаға басқан кезде ғана бал есептелінеді. Әрбір радиотопта бір ғана батырма дұрыс және ол бағдарламада өзінің топтық нөмірінің индексі бойынша белгіленеді, 0 – ден басталады. Бұл сұрақта дұрыс жауап бірінші жауап, радиобатырманың индексі 0 – ге тең және т.б. Бағдарламалық жолда
if TestDlg.RadioGroup1.ItemIndex=0 then ball:=ball+1;
шартты көшу командасы орындалады. Мұнда былай деп айтылады, егер тышқанмен бірінші топтың бірінші батырмасына шертсек (элемент индексі ItemIndex=0), онда ball айнымалысына 1 балл (ball:=ball+1) қосылады. Басқа жағдайда бұл команда орындалмайды. Осылайша TestDlg пішінінің барлық радиотобына жазып шығамыз. Тәжірибелік тұрғыдан алғанда бірдей жолдарды енгізуді жеңілдету үшін бірінші жолды жазғаннан кейін оны ерекшелеп, Edit менюінің Сору және Paste командаларын қолдана отырып, тағы да төрт көшірме жасап, оған сәйкесінше өзгертулер енгізіңіздер.
Бағдарламалық жолда
ResultDlg.Label1.Caption:=’Ваш результат:’+IntToStr(Ball);
ResultDlg пішінінде орналасқан Label1 құрауышының Caption қасиетіне 'Ваш результат:' деген мәтін және алынған балдар саны меншіктелінеді, IntToStr(Ball) (Integer to string сөздерінің басқы әріптері— бүтінді жолға айналдыру) функциясы ball айнымалысындағы бүтін санды жолдық форматқа айналдырады.
ResultDlg.ShowModal;
командасы Результат пішінін демонстрация жасайды.
Бағдарламаны орындап, онда өз жолдастарыңызды тестен өткізіңіздер және оларға Паскаль тілінде мұндай бағдарламаны құру үшін 1500 – ге жуық жол жазу керек, ал ол бір жұмалық немесе айлық уақытты алатынын айтыңыздар. Delphi тілін меңгеру арқылы мұндай бағдарламаны 30 минут уақыт ішінде жасауға болады. Delphi сияқты күшті, әрі әдемі бағдарламалық тілді үйреніп, біліп жатқандарыңызға мақтаныңыздар.
2 OBJECT PASCAL ТІЛІНДЕГІ ОБЪЕКТІЛІ – БАҒЫТТАЛҒАН БАҒДАРЛАМАЛАУ
Процедуралық бағдарламалау бағдарламаның негізі алгоритм, берілгендерді өңдеу процедурасы деп тұжырымдайды.
Объектілі - бағытталған бағдарламалау (ОББ) – ол негізінде нақты өмірдің объектісі мен тәртібіне сай келетін, қандай да бір құрылым ретінде қарастырылатын объект түсінігі бар бағдарламаны құрудың әдістемесі.
ОББ әдістемесінің қолданылуымен шешілетін тапсырмалар объект және оларға қолданылатын операциялар деген терминдермен сипатталады. Мұндай түрдегі бағдарлама объектілер жиыны мен олардың арасындағы байланысты көрсетеді.
Кластар мен олардың элементтеріне ат тағайындауда ұсынылатын ережелер:
Кластың аты Т префиксінен басталады.
Мысалы: TObject, TForm, TButton және т.б.
Кластың өрісі, қасиетке сай келеді (property), әдетте қасиеттің атымен аталады, бірақ F деген префикстен басталады.
Мысалы: FCount: Integer;
property Count: Integer read FCount write SetCount;
Әдістің параметрі, оның мәні қандай да бір өрістің класына меншіктеледі, өрістің атымен аталады, бірақ А деген префикстен басталады.
Мысалы: procedure SetCount(ACount: Integer);
Әдістің аты, оның көмегімен қасиеттің мәні оқылады, әдетте Get сөзінен басталады.
Мысалы: function GetParam: Integer;
Әдістің аты, оның көмегімен қасиеттің мәні жазылады, әдетте Set сөзінен басталады.
Мысалы: SetCount әдісі (жоғарыдан қараңыздар).
Конструктор әдісіне әдетте Create аты беріледі.
Мысалы: constructor Create(Owner: TComponent);
constructor Create(AName: String);
Деструктор әдісіне әдетте Destroy аты беріледі:
Мысалы: destructor Destroy; override;
Хабарламаны өңдейтін әдістердің аттары WM префиксінен басталады, хабарламаның типтерінің аттары - TWM , ал хабарламаның индексі - WM_ - префиксінен басталады.
Мысалы: procedure WMSetFocus (var Message: TWMSetFocus);
message WM_SetFocus;
message WM_Quit; {әр кез бағдарламаның орындалуын тез
арада тоқтату керек болғанда өрбиді}
Оқиғаның өңдеуішіне қатынауды жүзеге асыратын қасиеттің аттарына On префиксі бар ат тағайындалады.
Мысалы: property OnChange: TNotifyEvent read FOnChange write FOnChange;
2.1 Класс және объект туралы түсінік
ООБ – дың негізінде класс (class) және объект деген ұғымдар жатыр. Object Pascal – да класс деп - өріс, әдіс және қасиет деген ұғымдардан тұратын арнайы типті айтамыз. Кластың арғы - тегі болып объект деп аталатын, ескірген Turbo Pascal тілінің типі жатады. Объект Turbo Pascal тіліне Delphi - ді құрғанға дейін кіргізілген ұғым. Object Pascal тілінің жаңа нұсқасында пайда болған Delphi ортасында объектілер ескі бағдарламалық өніммен үйлесімділік үшін сақталған. Қазір объектіні қолдану маңызды емес.
Класс өз кезегінде нұсқағышты береді. Бірақ ол дәстүрлік нұсқағышқа қарағанда ерекше типтің нұсқағышы: онда класқа қатынағанда "^" символын қолдануға болмайды.
Класс –берілгендер мен оларға қолданылатын әрекеттерден тұрады.
Объект – кластың физикалық іске асырылуы (кластың экземпляры).
Класс өзінше бір сипатталатын тип болып табылады және типтерді жариялау бөлімінде жарияланады.
Мысалы:
type
TForm1 = class(TForm) { TForm1- TForm класының ұрпақ - класы}
{Аталық кластың өрісін, әдісін және қасиеттерін иемденеді}
Button1: TButton; {өріс}
Button2: TButton; {өріс}
L1: TLabel; {өріс}
L2: TLabel; {өріс}
procedure Button1Click(Sender: TObject); {әдіс}
procedure FormActivate(Sender: TObject); {әдіс}
private
{ Private declarations }
public
{ Public declarations }
end;
Класс бір жағынан жазба (record) – типіне де ұқсайды, ол берілгендердің өрісінен ғана емес,
Мысалы:
private
FCaption: String; {жолдық типтің өрісі}
FModified: Boolean; {логикалық типтің өрісі}
оларды өңдейтін бағыныңқы бағдарламалардан (әдіс),
Мысалы:
private
procedure SetCaption(Const ACaption: String);
procedure Close;
сонымен қатар өрістер мен әдістердің сипаттамалары бар қасиеттерден тұрады.
Мысалы:
public
property Caption: String read FCaption write SetCaption;
property Modified: Boolean read FModified write SetModified;
Сол себепті класта оның сипаттамалары мен тәртібі сипатталған.
Объект – белгілі бір класқа сай келетін айнымалыны береді және айнымалыны жариялау бөлімінде сипатталады. Мысалы:
var
Form1: TForm1;
Барлық кластарға сай келетін объектіні құра беруге болмайды. Олардың бірқатары әсіресе барлық кластардың иерархиялық ағашының басында орналасқаны бұны орындауға мүмкіндік бермейді, немесе олардың негізінде құрылған объектілер жұмыс істеуге қабілетсіз болып келеді, мысалы TObject ағымды класы. Ол мынамен байланысты, мұндай кластар сол немесе басқа аяқталған объектінің жан – жақты сипаттамасын бермейді (мысалы үшін, жиһаздың тек үлгісін ғана құруға болмайды, ал нақты стөл, нақты орындық және т.б. құруға болады). Мұндай кластар абстрактілі кластар деп аталады, сондықтан оларға абстрактілі әдістер сай келеді. Бұл ерекшелігіне қарамастан, мұндай кластарды құру тиімді, өйткені бұл кластарда барлық ұрпақтарында көп рет қайталамайтындай барлық кластарға тиісті жалпылықты жинақтауға болады.
ОББ үш негізгі қасиеттермен сипатталады:
инкапсуляция (encapsulation),
туындау (inheritance),
полиморфизм (polymorphism).
2.2 Инкапсуляция, туындау және полиморфизм
Класс - өріс, әдіс және қасиетті өзіне бүтіндей қоса отырып, жеке тапсырмаларды шешуге тағайындалған, аяқталған құрылымдық бірлік болып табылады. Әдетте мұндай тапсырма шешімі қандай да бір мәселелер жетегінің айналымында табылатын тапсырма болады. TRichEdit класы rtf-файлдардың (Rich Text Format форматындағы файл) қуатты мәтіндік редакторын береді, ол файлды көруді және редактрлеуді ұйымдастыруға, қаріптің өлшемі мен типін сақтау мен өзгертуге, символдар жолын іздеуге және т.б. тағайындалған. Өріс, әдіс және қасиеттің мұндай бүтіндігін инкапсуляция деп атаймыз.
Бұл тілде көптеген кластар бар (300 – ге жуық ), олар Delphi ортасын қолданатын бағдарламашыға арналып Object Pascal тілінің құрауыштарымен - Inprise International фирмасының қызметкерлерінің көмегімен құрылған.
Программист, бағдарламаны құра отырып өзінің пайдаланушы класын құрады. Мұндай кластар не айқын емес құрылады, онда программист Delphi ортасының көрнекілік құралдарын қолданады, ал кластың мәтінін Delphi өзі құрастырады, немесе айқын, онда программист кластың кодын Object Pascal тілінің құралдарымен өзі жазады.
Жаңа класс басқа қарапайым кластың негізінде құрылады. Ол үшін кластың тақырыбында оның аталық класын көрсету керек. Жаңа кластың тақырыбының синтаксисі мынандай түрде болады:
type className = class (ancestorClass)
мұнда className – жаңа кластың аты; ancestorClass – аталық кластың аты. Жаңа класс автоматты түрде өзінің аталық класының өрісін, әдісін және қасиеттерін иемденеді және өзінің өрісі, әдісі және қасиеттерімен толықтырылады. Кластың бұл қасиеті туындау деп аталады. Туындаудың көмегімен қарапайымнан қиынға өту әдісі арқылы, қандай болса да қиын дәрежедегі класты құруға болады. Қарапайым класс болып TObject табылады, ол өріс пен қасиеттен тұрмайды, бірақ кластың данасын құратын, жоятын, осы класқа қызмет көрсету және бағдарламаны қалыпты функциялауға арналған қандай да әдістердің жиынынан тұрады. Осының негізінде барлық аталық класқа ортақ кластың туындау ағашы құрастырылады. Мысалы:
type TPersistent = class (TObject),
type TComponent = class (TPersistent),
type TControl = class (TComponent).
Кейде аталық класта сипатталған әдістер қандай да бір себепке байланысты ұрпақ класты қанағаттандырмайды. Мұндай жағдайда ұрпақ класта аталық класта жазылғандай атпен әдіс құруға болады, бірақ жұмыс істеу принципі басқадай болады. Осыдан екі класта да бір атпен әртүрлі әдістер әрекет жасайтын болады. Полиморфизм бұл біратты әдістерді жариялауға мүмкіндігі бар туыс кластардың қасиеті.
2.3 Кластың синтаксисі
Барлық кластың синтаксисі мынандай түрде болады:
type
ClassName = class (AncestorClass)
MemberList
end;
мұнда ClassName – кластың аты; class – кілттік сөз; AncestorClass – аталық кластың типі; MemberList – өрістер, әдістер және қасиеттердің тізімі. Төменде TForm1 класынан тұратын main модулінің мәтіні көрсетілген.
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs;
type
TForm1 = class(TForm) { TForm1 класын жариялау}
Button1: TButton; {өріс}
Button2: TButton; {өріс}
L1: TLabel; {өріс}
L2: TLabel; {өріс}
procedure Button1Click(Sender: TObject); {әдіс}
procedure FormActivate(Sender: TObject); {әдіс}
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
i: Integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); {әдістің сипатталынуы}
begin
L1.Caption:= DateTimeToStr(Date);
L2.Caption:= TimeToStr(Time);
end;
procedure TForm1.FormActivate(Sender: TObject); {әдістің сипатталынуы}
begin
i:=125;
end;
end.
2.4 Кластың өрістері
Өріс деп кластағы инкапсуляцияланған берілгендерді айтамыз. Кластың өрістері жазбаның өрістері сияқты, бірақ айырмашылығы олар кез – келген типті болуы мүмкін, сонымен қатар кез – келген класс та бола алады, мысалы:
type
TChildClass = class(TObject) { TChildClass класын жариялау}
FOne: integer; {бүтін типтің өрісі}
FTwo: String; {жолдық типтің өрісі}
FThree: TObject; { TObject класс өрісінің типі}
end;
Ерер арғы тегі TObject класы болса, онда тақырыпта оны түсіруге болады.
Инкапсуляция принципі бойынша өрістерге қатынау кластың әдістері мен қасиеттерінің көмегімен жүзеге асырылады. Сонымен бірге Object Pascal - да өрістерге тікелей қатынауға да мүмкіндік берілген. Өріске қатынау үшін құрамды ат жазу қажеттігі туады, ол нүкте арқылы ажыратылған кластың аты мен өрістің атынан тұрады, мысалы:
var
MyObject : TChildClass;
begin
MyObject := 16;
MyObject := ’Некоторое строковое значение’;
end;
Ұрпақ – класының өзінің арғы – тегінің барлық өрістеріне қатынауға мүмкіндігі бар, бірақ оларға қол жеткізу мүмкін емес болғандықтан, оларды анықтауға болмайды. Мысалы:
type
TPredok = class {арғы тек класын жариялау}
Value: Integer;
end;
TPotomok = class(TPredok) {ұрпақ класын жариялау}
Value: String; {туындау өрісінің қабысуы}
end;
var
My1: TPredok; {класс айнымалысын жариялау (My1 –айнымалы-объект)}
My2: TPotomok; {класс айнымалысын жариялау (My2 – айнымалы-объект)}
begin
My1 := TPotomok.Create; { TPredok класының объектісін құрады }
My2 := TPotomok.Create; { TPotomok класының объектісін құрады}
My1.Value := 'Hello!'; {қате, TPredok өрісінің типі емес}
My2.Value := 'Hello!'; {дұрыс, Value: String өрісі жұмыс істейді}
My2.Value := 8; {қате: Value: Integer өрісі қалқаланған}
end;
Бұл мысалда екі класс сипатталған: TPredok – арғы тек және TPotomok – ұрпақ кластары. Әр класс біратты әртүрлі типті Value өрісінен тұрады.
Ары қарай var-секциясында әртүрлі class типті екі айнымалы - My1 және My2 жарияланған. Бір қарағанда My1:= TPotomok.Create объектісінің оператор – конструкторы TPotomок типті My1 объектісін құруы мүмкін (оны құруға жады бөледі). Бірақ My1 басқа типті болғандықтан , ол олай емес. Осы себептен конструктор аталық типті объект құрады, яғни TPredok типті объект. Енді келтірілген мысалдардағы бірнеше операторлардағы қателердің көзі түсінікті болды.
2.5 Кластың әдістері
Кластың әдісі болып инкапсуляцияланған процедура мен функция табылады. Бұл бағыныңқы бағдарламалар кәдімгі бағыныңқы бағдарламалар сияқты жарияланады. Әдіс кластың сипаттамасында жеке тақырып ретінде жариялануы керек, ал әдістің коды - implementation секциясында "." символын, әдістің өзінің класына қатысын білдіреді, нұсқау арқылы сипатталған, мысалы:
type
TMyClass = class(TObject) {класты жариялау}
...
procedure DoSomething; {DoSomething әдісін жариялау}
...
end;
DoSomething әдісіне сипаттама кейінірек модульдің implementation секциясында келтірілуі керек, мысалы:
procedure TMyClass.DoSomething; {тақырыптың түрі: класс. әдіс}
begin
...
end;
Әдіске қатынағанда құрамды атты немесе With операторын қолдануға болады, мысалы:
type
TChildClass = class(TObject) {класты жариялау}
...
function FirstFunc(x:real):real;
procedure SecondProc;
...
end;
...
var
MyObject : TChildClass;
y : real;
begin
...
MyObject.SecondProc; // әдіске қатынаудың екі мысалы
y := MyObject.FirstFunc(3.14); //құрамды аттың көмегімен: класс . әдіс
...
With MyObject do // сол қатынау
begin // With опреаторының көмегімен
SecondProc;
y := FirstFunc(3.14);
end;
...
end;
Класта анықталған әдістер статикалық, виртуальды, динамикалық және абстрактілі болуы мүмкін. Методтың типі оның ұрпақтарымен қалқалану механизмі арқылы анықталады.
Біратты әдістер ұрпақтарда мысалда көрсетілгендей өрістердің қалқалануы сияқты қалқаланады . Мұндай қалқалау статикалық деп аталады. Статикалық әдістер үшін қалқалау компилятор арқылы жүзеге асырылады. Үнсіздікпен класта сипатталған барлық әдістер статикалық болып табылады.
Мүмкіндікті кеңейту үшін жиі динамикалық қалқалау қолданылады. Ол үшін аталық әдіс dinamic (динамикалық әдіс) немесе virtual (виртуальды әдіс) директивасынан тұруы керек, ал ұрпақ класта қалқалау әдісі - override директивасынан тұруы керек. Мысалы:
type
TFigure = class
procedure Draw; virtual; {виртуальды әдіс}
end;
TRectangle = class(TFigure)
procedure Draw; override; {қалқалау әдісі}
end;
TEllipse = class(TFigure)
procedure Draw; override; {қалқалау әдісі}
end;
Бұл мысалда TFigure аталық класының Draw виртуальды әдісі жарияланған және екі біратты әдіс TRectangle және TEllipse ұрпақ класына қатысты жарияланған. Соңғылары қалқаланумен жарияланған (override).
Мұндай жариялау керекті мақсатқа жету мақсатында әдістерді қалқалауға мүмкіндік береді:
var
Figure: TFigure;
begin
Figure := TRectangle.Create; // кластың данасын құру
Figure.Draw; // TRectangle.Draw әдісін шақыру
Figure.Destroy; // класс данасын жою
Figure := TEllipse.Create; // класс данасын құру
Figure.Draw; // TEllipse.Draw әдісін шақыру
Figure.Destroy; // класс данасын жою
end;
Семантикалық виртуальды және динамикалық әдістер біркелкі жұмыс істейді. Айырмашылығы тек виртуальды әдіс уақытты үнемдеу көз қарасында өте тиімді (есептеу жылдамдығын тиімдейді), ал динамикалық әдіс оперативтік жадыны рациональды қолдануға мүмкіндік береді (сәйкес келетін бағдарламалық кодтың өлшемін тиімдейді). Динамикалық және виртуальды әдістер статикалық әдістен ерекшелігі мынада , аталық әдістер мен ұрпақтар әдістерінің орын ауыстыруы бағдарламаның орындалу барсыныда жүзеге асырылады.
Класта әдіс abstract директивасының көмегімен абстрактілі болып жариялануы мүмкін. Мұндай әдіс виртуальды немесе ддинамикалық әдіс болуы мүмкін, бірақ басқа әдістерден айырмашылығы implementation секциясында өзінің коды болмауы мүмкін. Ол класта анықталады, бірақ ешқандай әрекеттен тұрмайды, ешқашан шақырылмайды және ұрпақтар класында қайтадан анықталуы керек. Абстрактілі әдістен тұратын класс абстрактілі класс деп аиалады. Мұндай кластар мен әдістер ұрпақтар әдістеріне қатынау тәсілін инкапсуляция жасайды, бірақ өздері ештеңе істемейді, мысалы:
procedure DoSomething; virtual; abstract;
Қалқаланбаған абстрактілі әдіске қатынау орындалу уақыты туралы қатені шақырады (run time error), мысалы:
type
TClass1 = class(TClass0)
...
procedure Paint; virtual; abstract;
end;
TClass2 = class(TClass1)
...
procedure Paint; override;
end;
var
jClass1: TClass1;
jClass2: TClass2;
begin
jClass1.Paint; // абстрактілі әдіске қатынау дұрыс емес
jClass2.Paint; // дұрыс
...
end;
Әрбір класс екі ерекше әдістен тұрады – конструктор және деструктор. Конструктор объектіні құру және оны инициализациялау үшін тағайындалған. Мәселен, Object Pascal тілінде объект динамикалық құрылым болып табылады және айнымалы-объект берілгендерден емес оларға сілтемеден тұрады. Конструктор объектіні динамикалық жадыда үлестіреді және объектінің өрісіне алғашқы мәнін меншіктейді. Соған байланысты тізбектелген типтің өрісі алғашқы мән ретінде 0 – ді алады, жолдық тип ретінде – бос жол, нұсқағыш өрістер - nil мәнін, таңдау - өрісі - Unassigned мәнін алады. Одан басқа, конструктор динамикалық жады бөлінгеннен кейін құрылған объектіге сілтемені Self айнымалысына орналастырады. Барлық класс үнсіздікпен Self айнымалысынан тұрады, ол автоматты түрде класта жарияланады.
Деструктор, конструкторға қарама – қарсы ұғым, ол кластың данасын жоюға арналған, яғни жадының объектіні бұзу және жойылатын объектімен бос емес бөлігін босату. TObject базалық класының және оның ұрпақтарында конструктор мен деструктор Create (құру) және Destroy (жою) сәйкес аталады. Бұл класта сонымен қатар Free әдісі жарияланған, ол алдымен адрестің корректілігін тексереді (объект шын мәнінде жүзеге асырылған ба ?) және содан кейін барып қана Destroy әдісін шақырады. Егер объект конструктормен құрылмаған болса, онда деструкторға қатынау ерекше жағдайдың генерациясына әкеп соғады. Мұндай байланыста Destroy әдісінің орнына Free әдісін қолданған жөн болады.
Конструктор мен деструктор процедура болғанымен де, олар арнайы резервтелген сөздермен жарияланады. Конструктор constructor сөзімен, ал деструктор – destructor сөзімен жарияланады.
type
TSample = class
Text: String;
constructor Create; // кластың данасын құру
destructor Destroy; // кластың данасын
end;
Өріске, қасиеттерге және әдістерге қатынамас бұрын, ең алдымен оларды құру керек. Объектіні құру үшін ең алдымен объектінің класына конструктор-әдісін қолдану қажет:
var
MyObject: TSample;
begin
...
MyObject := TSample.Create;
...
end;
Егер ұрпақтар класы құрылып жатса және оны құру кезінде аталық класта жоқ кейбір қосымша әрекеттерді іске асыру көзделсе, онда алдымен өзінің аталығының конструкторын шақыру керек, ал содан кейін барып қосымша әрекеттерді іске асыру қажет. Арғы тектің өрістеріне қатынауды қамтамасыз ету үшін, конструкторда алдын – ала арғы тек класының объектісін құру қажет. Аталық кластың кез – келген қалқаланған әдісін шақыруды резервтелген inherited (иемденген) сөзінің көмегімен іске асырады. Мысалы:
type
TShape = class(TGraphicControl)
private {ішкі жариялау}
FPen: TPen;
FBrush: TBrush;
procedure PenChanged(Sender: TObject);
procedure BrushChanged(Sender: TObject);
public {сыртқы жариялау}
constructor Create(Owner: TComponent); override;
destructor Destroy; override;
...
end;
...
constructor TShape.Create(Owner: TComponent);
begin
inherited Create(Owner); // TGraphicControl арғы тек класының объектісін құру
Width := 65; // TGraphicControl иемденген қасиетін өзгерту
Height := 65;
FPen := TPen.Create; // class TPen типі бар жеке өрісті құру
FPen.OnChange := PenChanged;
FBrush := TBrush.Create; // class TBrush типі бар жеке өрісті құру
FBrush.OnChange := BrushChanged;
end;
Кейбір қарапайым кластар конструкторды немесе деструкторды жарияламай – ақ, құрылуы немесе жойылуы мүмкін. Мысалы, класс TObject, класының ұрпағы болып келсе, онда мұнда Constructor мен Destructor - ды жариялаудың қажеті жоқ:
type
TClassy = class;
...
var
Classy: TClassy;
...
Classy:= TClassy.Create; {объектіні құру}
...
Classy:= TClassy.Free; {объектіні жою}
Тілде бір класс аралығында бір атпен бірнеше әдісті жариялау мүмкіндігі бар. Осыдан кез – келген осындай әдіс қайта іске қосылатын болуы керек (overload директивасы). Компилятор мұндай әдістерді өзінің тиімді формальды параметрлерінің жиынымен идентификациялайды. Сол атпен пайда болған әдіске Delphi компиляторының реакциясын орындатпау үшін, әрбір осындай әдісті reintroduce директивасымен белгілеп қою керек.Ары қарай implementation секциясында осындай барлық әдістердің қодтарын енгізу керек. Мысалы:
type
TClassy = class;
Procedure HH(i, j: byte; var s: String); reintroduce; overload;
Procedure HH(q: String); reintroduce; overload;
Procedure HH(a: array of Integer); reintroduce; overload;
end;
...
implementation
...
procedure TClassy.HH(i, j: byte; var s: String);
begin
S:=IntToStr(i + j);
end;
procedure TClassy.HH(q: String);
begin
Label2.Caption:= q;
end;
procedure TClassy.HH(a: array of Integer);
begin
Label1.Caption:= IntToStr(a[6] + a[4]);
end;
...
Енді TClassy.HH аты бар әдіске қатынағаннан кейін, бағдарлама қатынағанда формальды параметірі нақты параметіріне сай келетін әдісті ғана шақырады.
2.6 Кластың қасиеттері
Қасиеттер, өріс сияқты кластың атрибуты болып саналады. Қасиеттер сырт көрінісімен кластың өрісін еске түсіреді, бірақ шынында ол өрістерге қатынасты реттейтін механизм болып табылады. Объектінің қасиеттері мыналармен сипатталады:
оның қасиеттің мәнін сақтайтын кластың өрісімен байланысы;
қасиеттің өрісіне қатынауды қамтамасыз ететін екі әдіс:
қасиеттің мәнін тағайындайтын әдіс қасиетті жазу әдісі (write) деп аталады.
қасиеттің мәнін алатын әдісті қасиетті оқу әдісі (read) деп атаймыз.
Қасиетті property, read және write сөздерінің көмегімен жариялайды. Read және write сөздері әдістердің аттарынан тұратын бөлімнің басын білдіреді, олар сәйкес оқу мен жазуға тағайындалған. Қасиеттің синтаксисі мынандай:
property propertyName[indexes]: type index integerConstant specifiers;
мұндағы propertyName – қасиеттің аты, кез – келген дұрыс идентификатор; [indexes] – [имя1, имя2, ... , имяN: type] формасындағы ат - параметрі; type – қасиеттің типі, ол құрамдас немесе алдын – ала типтерді жариялау бөлімінде жариялануы қажет; index integerConstant – бүтін санды тұрақты шама, міндетті емес параметр, ол бірнеше қасиеттерге әртүрлі мәндерді көрсетуде сол бір әдісті қолдануға мүмкіндік береді (мысал 2.6.2); read, write, stored, default (немесе nodefault) және implements – спецификаторлары (specifiers).
Мысал 2.6.1 Object Pascal - да анықталған қасиеттерге мысалдар.
property Objects[Index: Integer]: TObject read GetObject
write SetObject;
property Pixels[X, Y: Integer]: TColor read GetPixel
write SetPixel;
property Values[const Name: string]: string read GetValue
write SetValue;
property ErrorCount: Integer read GetErrorCount;
property NativeError: Longint read FNativeError;
Мысал 2.6.2 Index спецификаторы бар қасиетке мысал.
type
TRectangle = class
private
FCoordinates: array[0..3] of Longint;
function GetCoordinate(Index: Integer): Longint;
procedure SetCoordinate(Index: Integer; Value: Longint);
public
property Left: Longint index 0 read GetCoordinate
write SetCoordinate;
property Top: Longint index 1 read GetCoordinate
write SetCoordinate;
property Right: Longint index 2 read GetCoordinate
write SetCoordinate;
property Bottom: Longint index 3 read GetCoordinate
write SetCoordinate;
property Coordinates[Index: Integer]: Longint read GetCoordinate write SetCoordinate;
...
end;
Index спецификаторы бар қасиетте қатынау әдісі бүтін типті қосымша параметрді алуы керек. Оқу функциясы үшін ол жалғыз параметр, жазба процедурасы үшін ол соңғы параметрдің алдындағы (қасиеттің мәнін анықтайтын алдыңғы параметрге сай) параметр болуы керек. Бағдарлама қасиетке қатынағанда, бүтін санды тұрақты шама қасиет автоматты түрде қатынау әдісіне беріледі.
Егер Rectangle TRectangle типті болса, жоғарыда жарияланғандай, онда
Rectangle.Right := Rectangle.Left + 10;
мынадай сәйкестік орын алады:
Rectangle.SetCoordinate(2, Rectangle.GetCoordinate(0) + 100);
Қасиеттердің барлық жариялануында read және write спецификаторларының біреуі немесе екеуін бірақ болуы қажет. Олар қатынас спецификаторы деп аталады және келесі формада жазылады:
read fieldOrMethod
write fieldOrMethod
мұндағы fieldOrMethod – қасиет жарияланған класта немесе арғы – тек класында жарияланған өріс немесе әдістің аты.
Егер fieldOrMethod қасиет жарияланған класта жарияланса, ол қасиетті жарияламас бұрын орындалуы қажет.
Егер fieldOrMethod арғы – тек класында жарияланса, онда ол ұрпақта көрінуі тиіс, яғни басқа модульде жарияланған жеке өріс немесе ұрпақ кластың әдісі болмауы тиіс.
Егер fieldOrMethod - өріс болса, онда ол қасиеттің типінен тұруы керек.
Если fieldOrMethod - әдіс болса, онда оны қайта анықтауға болмайды.
Если fieldOrMethod - read спецификаторында анықталған әдіс болса, онда ол қасиеттің типіне сай келетін мәнді қайтаратын параметрі жоқ функция болуы керек. Оқуға арналған функцияның аты соңынан қасиеттің аты жазылатын Get приставкасынан басталады.
Егер fieldOrMethod - write спецификаторында анықталған әдіс болса, онда ол бір ғана параметрден тұратын процедура болуы тиіс. Бұл параметрдің типі қасиеттің типіне сай келуі тиіс. Жазуға тағайындалған процедураның аты соңынан қасиеттің аты жазылатын Set приставкасынан басталады.
Мысалы, егер қасиет жарияланған болса:
property Color: TColor read GetColor write SetColor;
онда GetColor әдісі мыналай сипатталуы қажет
function GetColor: TColor;
және SetColor әдісі мыналай сипатталуы
procedure SetColor(Value: TColor);
немесе
procedure SetColor(const Value: TColor);
сипатталынуы керек.
Егер қасиет тек read спецификатрынан тұратын болса, онда ол "read only" (тек оқуға ғана) атрибутынан тұрады. Егер қасиет тек write спецификатрынан тұратын болса, онда ол "write only" (тек жазуға ғана) атрибутынан тұрады. Қасиеттің мәніне тек оқуға ғана тағайындалған мәнді меншіктеу немесе қасиеттің өрнегінде тек жазуға ғана арналған мәнді қолдану компиляция уақытының қатесін шақырады. Жазудан қорғалған қасиетке мәнді объектіні инициализациялау кезінде орнатуға болады.
Мысал 2.6.3 Name және Address екі қасиеттерден тұратын Name және Address TPerson класын сипаттау.
type
TName = string[15];
TAddress = string[35];
TPerson = class // класты жариялау
private
FName: TName; // Name қасиетінің мәні
FAddress: TAddress; // Address қасиетінің мәні
protected
constructor Create(Name: TName);
procedure Show;
function GetName: TName;
function GetAddress: TAddress;
procedure SetAddress(NewAddress: TAddress);
public
property Name: TName // Name қасиеті
read GetName; // тек оқуға ғана мүмкіндік бар
property Address: TAddress // Address қасиеті
read GetAddress // оқуға және жазуға мүмкіндік бар
write SetAddress;
end;
Мұндағы Name – FName өрісімен байланысқан қасиет, GetName – FName өрісінен оқуға тағайындалған әдіс. Address – FAddress өрісімен байланысқан қасиет, GetAddress және SetAddress – сәйкес FAddress өрісіне оқуға және жазуға тағайындалған әдіс.
Төменде TPerson класының объектілерін құруға және оның қасиеттеріне қатынауды қамтамасыз ететін TPerson класының әдістері келтірілген.
constructor TPerson.Create(Name: TName); // TPerson класының конструкторы
begin
FName := Name;
end;
function TPerson.GetName; // Name қасиетінің мәнін алатын әдіс
begin
Result := FName;
end;
function TPerson.GetAddress; // Address қасиетінің мәнін алатын әдіс
begin
Result := FAddress;
end;
// Address қасиетінің мәнін өзгертетін әдіс
procedure TPerson.SetAddress(NewAddress: TAddress);
begin
If FAddress = ’’ then FAddress := NewAddress;
end;
Қасиетке қатынау үшін бағдарламаның мәтінінде өрістер мен әдістердегі сияқты объектінің атынан, нүктеден және қасиеттің атынан тұратын құрамды атты қолдану керек, мысалы:
var
Student : TPerson // кластың айнымалысын жариялау
HisAddress : String;
begin
Student := TPerson.Create(’Иванов’);
Student.Address := ’ул. Садовая, д.3, кв.25’;
...
HisAddress := Student.Address;
...
Student.Free;
end;
Address қасиетіне мән меншіктеу нұсқасын орындағанда компилятор әдісті шақыру нұсқасында оны қайта трансляциялайды.
Student.SetAddress(’ул. Садовая, д.3, кв.25’);
Сырт жағынан қарағанда бағдарламада қасиетті қолданудың объектінің өрісін қолданудан еш айырмашылығы жоқ. Бірақ қасиет пен объектінің өрісінің арасында принциптік айырмашылық бар: қасиетке мән меншіктегенде және оның мәнін оқығанда қандай да бір жұмысты атқаратын процедура автоматты түрде шақырылады. Мысалы, біз FAddress өрісіне тікелей керекті мәнді орналастыра аламыз
Student.FAddress := ’ул. Садовая, д.3, кв.25’;
Бірақ, Address қасиетін қолдана отырып біз тек оқу мен жазуға тағайындалған әдістерге әртүрлі әрекет жасай аламыз: қасиетке меншіктелген мәннің корректілігін тексеру, экранға хабарламаның шығуын қамтамасыз ету, экрандағы объектінің сырт көрінісін өзгерту және т.б. Егер жазу немесе оқу кезінде қосымша әрекеттердің қажеттігі тумаса, онда сәйкес әдістің орнына өрістің атын нұсқау қажет:
type
TPerson = class
FAddress: TAddress;
procedure SetAddress(NewAddress: TAddress);
property Address: TAddress read FAddress write SetAddress;
end;
Қасиет нақты бір өріспен байланыспауы да мүмкін. Бұл жағдайда қасиетте қасиеттің типіне сай келетін берілгендермен әрекет жасау үшін екі әдіс анықталады.
2.7 Кластың құрылымы. Кластың элементтерінің көріну аймағы
Object Pascal объектілерінің модельінде оларды қай аймақта қолдануға болатындығын анықтайтын (көріну аймағы) құрамды бөліктерге қатынасты қамтамасыз ететін механизм бар. Барлық класс секциядан тұратын құрылымнан тұрады. Әрбір секция арнайы резервтелген сөздермен жарияланады. Олардың қатарына: published (декларацияланған), private (меншік), protected (қорғалған), public (қатынас бар), automated (автоматталған). Әрбір секцияның ішінде ең алдымен өріс , одан кейін әдіс, қасиет және оққиға жарияланады. Класс құрылымына мысал:
type
TMyClass = class(TControl)
private
... {меншік жариялану мына жерде}
protected
... {қорғалған жариялану мына жерде}
public
... {қатынас бар жариялану мына жерде}
published
... { жариялану мына жерде}
end;
Секциялар кластың құрамына кіретін элементтердің көріну аймағын анықтайды:
Private – көріну аймағын минимумге дейін кішірейтеді: сипаттаудың жабық элементтеріне тек класс сипатталған модульде орналасқан берілген кластың және бағыныңқы бағдарламаның әдістерінің ішінде ғана қатынауға болады. Private секциясында анықталған элемент басқа модульдерде орналасқан жақын ұрпақ кластарға да қол жетпейтін болып қалады. Әдетте private секциясына класс өрістерінің сипаттамасын орналастырады, ал осы өрістерге қатынасты қамтамасыз ететін әдістерді protected секциясына орналастырады.
Public – класс жарияланған uses тізімінде модульге сілтемеден тұратын ағымды және кез – келген бағдарламаның модулінде көрінетін элементтер жиынынан тұрады.
Published – ол Public сияқты, бірақ айырмашылығы тек мынада, published секциясы құрауыштарды жариялауда қолдану үшін арнайы даярланған. Бұл секцияға орналастырылған қасиеттер тек бағдарламаның орындалу барысында ғана емес сонымен қатар көрнекілік конструкциялау кезінде Объект Инспекторының терезесінде де оған қатынауға болады. Сондықтан published секциясында жарияланған өрістер класс типтес болуы керек. Пішін (мысалы, TForm1) класының жариялануының басында орналасқан аты жоқ секция, үнсіздікпен published секциясы болып табылады.
Protected – кластың және оның кез – келген ұрпақ кластарының әдістеріне ғана қатысты элементтерден тұрады және олар сол модульде орналасты ма? жоқ па? одан тәуелсіз. Әдетте protected класына кластың әдісінің сипаттамасын орналастырады.
Automated – OLE-объект Автоматизацисы интерфейсіне қосылатын қасиеттер мен әдістерді жариялауға қолданылады. Бұл секцияның мүшелерінің көріну аймағы шектелмеген.
Бір кластың төңірегінде ретсіз кез – келген секция құрылуы мүмкін. Секциялардың орналасу тәртібі де әртүрлі болуы мүмкін. Сонымен қатар кез – келген секция бос болуы мүмкін.
2.8 Кластарға операциялар қолдану. IS және AS кілттік сөздері
Кластарға екі операция қолдануға рұқсат етілген – IS және AS операциялары.
1. IS операторы.
IS операторының көмегімен берілген класс нұсқалған типке тиісті ме соны анықтауға болады. IS операторынан тұратын өрнектің синтаксисінің түрі мынандай болады:
object is class
Бұл өрнек логикалық типтен (boolean) тұрады, егер object айнымалысы class класының объектісі немесе кластардың біреуінің объектісі болса, онда TRUE мәнін қайтарады, әйтпесе – FALSE.
Мысал 2.8.1
IF ActiveControl IS TEdit THEN ...
IS операторы бульдік мәнді қайтарады.
TRUE – егер тексерілетін айнымалы ActiveControl берілген типке қатысты болса (TEdit). Сонымен қатар нұсқалған тип тексерілетін айнымалының арғы – тегі болып табылса (яғни ActiveControl TEdit класының немесе одан туындаған бір кластың объектісі болса).
FALSE – кері жағдайда.
Мысал 2.8.2
IF ActiveControl IS TObject THEN DoSomeThing;
Барлық кластар TObject класының ұрпақ кластары болғандықтан, DoSomeThing процедурасы кез – келген жағдайда орындалады.
2. AS операторы.
AS опрераторы нұсқағышты нақты типке келтіру үшін қолданылады. AS операторынан тұратын өрнектің синтаксисінің түрі мынандай болады:
object as class
Бұл өрнектің есетелінуінің нәтижесі болып class класының типіне немесе class класының ұрпақ – класының типіне сай келетін объектіге сілтеме табылады. Бағдарламаның орындалу барысында object class класы типті немесе class класының ұрпақ – класының типті немесе nil типті болуы мүмкін. Үйлеспеген типке келтіру ерекше жағдайдың өрбуіне әкеп соғады.
Мысал 2.8.3
WITH ActiveControl AS TEdit DO DoSomeThing;
Келтірілген фрагментте ActiveControl айнымалысы қандай да бір класқа нұсқағыш болуы мүмкін. AS операторының көмегімен бұл нұсқағыш TEdit – тегі нұсқағышқа түрленеді. Егер ActiveControl айнымалысы TEdit типінің (немесе оның бір ұрпақ кластарының) объектісі болып табылмайтыны анықталса, онда типтің келтірілуі орындалмайды және DoSomeThing әдісі шақырылмайды. Кері жағдайда типтердің келтірілуі орындалады және DoSomeThing әдісі шақырылады.
Мысал 2.8.4
with Sender as TButton do // егер Sender TButton типтен тұрса
begin // немесе TButton – нан ұрпақ -тип
Caption := '&Ok';
OnClick := OkClick;
end;
...
(Sender as TButton).Caption := '&Ok'; // TButton немесе оның ұрпақтары типтес
// Sender айнымалысының Caption қасиетіне '&Ok' мәні меншіктеледі
2.9 Оқиға және меншіктеу
Windows жүйесінде бұрыннан жұмыс істеп келе жатқан программистке "оқиға" терминінің мағынасын ұқтырудың қажеті жоқ шығар. Осы орта мен ол үшін жазылған бағдарламаның барлығы қолданушы, компьютер аппаратурасы немесе басқа бағдарламаның әсерінің нәтижесінде өрбитін оқиға арқылы басқарылады. Оқиғаның басталуы туралы хабар – ол терезе функцияларының көмегімен алынған Windows жүйесінің хабарламалары.
Қолда анықтамалық бола тұра, мұндай санды хабарламалармен жұмыс істеу оңайға түспейді. Сондықтан Delphi – дің артықшылықтарының бірі болып программистің Windows хабарламаларымен жұмыс істеу қажеттілігінен арылғаны болып табылады (бірақ оның мұндай мүмкіншілігі бар; ол туралы келесі бөлімде айтамыз). Delphi – де типтік оқиғалардың саны екі ондықтан аспайды және олардың барлығы орта туралы терең білімді қажет етпейтін қарапайым интерпретациядан тұрады.
Object Pascal тілінің деңгейінде іске оқиғалар қалай іске асырылғанын қарастырайық.
Оқиға — бұл сырттан келген әсерлерге қолданушының реакциясын құруға тағайындалған процедуралық типтің қасиеті. Мұндай қасиеттің мәні болып қандай да бір әдіске нұсқағыш табылады.
Оқиғаны сипаттаудың синтаксисі мынадай:
property OnMyEvent: TMyEvent read FOnMyEvent
write FOnMyEvent;
мұндағы OnMyEvent – қасиет-оқиғаның аты, TMyEvent – оқиғаның процедуралық типі, FOnMyEvent — өріс, ол сәйкес келетін оқиғаны өңдейтін әдіске нұсқағышты сақтауға тағайындалған.
Мұндай қасиетке мән тағайындау дегеніміз - объектіге оқиға шақырылған кезде шақырылатын әдістің адресін нұсқау. Мұндай әдістер оқиғаны өңдеуіштер деп аталады. Мысалы, мына жазу:
Application.OnActivate := MyActivatingMethod;
Application (осылай жұмыс істеп тұрған қосымшаға сай келетін объект аталады) объектісі активтелгенде MyActivatingMethod өңдеу - әдісі шақырылатынын білдіреді.
Кітапхананың ішінде Delphi – дің орындалу уақытында Windows хабарламаларын өңдейтін оқиғаны өңдеу шақыртулары әдістерде орналастырылады. Қажетті әрекеттерді орындағаннан кейін бұл әдіс өңдеушініңадресі белгіліме соны тексереді, ал егер ол белгілі болса, онда оны шақырады:
if Assigned(FOnMyEvent) then FOnMyEvent(Self);
Оқиға пайда болғанына және тағайындалуына байланысты параметрлерінің әртүрлі саны мен типінен тұрады. Барлығына жалпы болып Sender параметрі табылады, ол оқиғаның объект-көзіне нұсқайды. Ең қрапайым процедуралық тип — TNotifyEvent – оның екі параметрі болмайды:
TNotifyEvent = procedure (Sender: TObject) of object;
Мысал 2.9.1 Мысал ретінде TControl класының стандарты оқиғаларының OnDblClick (тышқанның сол жақ батармасына екі рет шерткенде өрбиді), OnMouseDown (тышқанның батырмасын басқанда өрбиді) және OnMouseMove (тышқанды жылжытқанда өрбиді ) сипатталуын қарастырайық:
type
TControl = class(TComponent)
private
..............................
FOnDblClick: TNotifyEvent;
FOnMouseDown: TMouseEvent;
FOnMouseMove: TMouseMoveEvent;
..............................
protected
..............................
property OnDblClick: TNotifyEvent read FOnDblClick
write FOnDblClick;
property OnMouseDown: TMouseEvent read FOnMouseDown
write FOnMouseDown;
property OnMouseMove: TMouseMoveEvent read FOnMouseMove
write FOnMouseMove;
..............................
end;
FOnDblClick, FOnMouseDown и FOnMouseMove – оқиға-қасиетін сипаттағанда қолданылатын өрістер. Өрістерді сипаттағанда қолданылатын процедуралық типтер келес түрде анықталады:
type
TNotifyEvent = procedure (Sender: TObject) of object;
TMouseEvent = procedure (Sender: TObject; Button: TMouseButtton;
Shift: TShiftState; X, Y: Integer) of object;
TMouseMoveEvent = procedure (Sender: TObject; Shift: TShiftState;
X, Y: Integer) of object;
Процедуралық типтерге жалпы болып оқиғаның объект-көзіне нұсқағыштан тұратын Sender параметрі табылады. Button параметрі тышқанның қай батырмасы басылғандығы туралы ақпараттан тұрады. Shift параметрі пернетақтада басылған батырманың кодынан тұрады. X және Y – құрауыштың шегіндегі тышқанның ағымды координаталары.
Инспектор объектісінің Events парағының кез – келген оқиғасының өрісіне шерту арқылы, сіздер бағдарламада керекті типтің әдісінің дайындамасын аласыздар. Мұнда ат ағымды құрауыш пен оқиғаның атынан тұратын болады (On префикісі болмайды), ал ол ағымды пішінге тиісті болады. Form1 пішінінде Label1 белгісі бар деп ұйғарайық. Онда тышқанмен шерту өңдеуішіне (OnClick оқиғасы) TForm1 класының Label1Click әдісінің тақырыбы құрылады:
procedure TForm1.Label1Click(Sender: TObject);
begin
...
end;
Оқиға объектінің қасиеті болып табылғандықтан, олардың мәнін бағдарламаның орындалу барысының кез – келген жерінде өзгертуге болады. Мұндай тамаша мүмкіндік атын қайта өзгерту деп аталады. Кез – келген уақытта бір объектінің оқиғаға реакциясының тәсілін алып, оны келесі бір объектіге қайта тағайындауға болады:
Object1.OnMouseMove := Object2.OnMouseMove;
Меншіктеу принципі әрбір арнайы жағдай үшін жаңа еншілес кластың тууы деген үлкен үрдістің пайда болуының алдын алады және ондай үрдістерді қарапайым процедураларды қоюмен айырбастайды.
Қандай механизм өңдеуішерді ауыстыруға мүмкіндік береді?, өйткені ол жай ғана процедура емес, әдіс қой. Бұл жерде Object Pascal тілінің әдіске нұсқағыш деген ұғымы сай келеді. Әдіс қарапайым процедурадан айқын сипатталған параметрлерден басқа әдіске айқын емес түрде класта автоматты түрде анықталған Self айнымалысына орналастырылатын оны шақырған объектіге нұсқағыштан тұрады. Сипатталып отырған процедуралық тип әдіске тағайындалғанын (яғни Self – ті алуды қарастырады), яғни әдістің типі болып келгенін көрсету үшін процедураны сипаттағанда of object резервтелген сөзді қосу керек. Әдіске нұсқағыш дегеніміз – ол осындай процедураға нұсқағыш болып табылады.
type
TMyEvent = procedure(Sender: TObject; var AValue: Integer) of object;
T1stObject = class;
FOnMyEvent: TMyEvent;
property OnMyEvent: TMyEvent read FOnMyEvent write FOnMyEvent;
end;
T2nd0bject = class;
procedure SetValuel(Sender: TObject; var AValue: Integer);
procedure SetValue2(Sender: TObject; var AValue: Integer);
end;
var
Obj1: T1stObject;
Obj2: T2nd0bject;
begin
Obj1 := T1stObject.Create ;
Obj2 := T2nd0bject.Create;
Obj1.OnMyEvent := Obj2.SetValue1;
Obj1.OnMyEvent := Obj2.SetValue2;
...
end.
Бұл мысал атын қайта өзгерткен кезде басқа кластардың да әдістерін меншіктеуге болатындығын көрсетеді. Мұнда Objl объектісінің OnMyEvent оқиғасының өңдеуіші болып ретпен Obj2 объектісінің SetValue1 және SetValue2 әдістері табылады.
Объект Инспекторының Events бетінде әдістің, яғни оқиғаның типіне сай келетін құрауыштың қасиеттері бейнеленеді. Қандай да бір оқиғаға қойылатын оқиғанының өңдеуішінің типі оқиғаның типіне сай болуы керек, сондықтан әдістің типін басқаша оқиға өңдеуішінің типі деп те атауға болады.
Бақылау сұрақтары:
Класс пен оның элементтеріне ат тағайындағанда ұсынылатын ережелер.
Класс дегеніміз не? Объект дегеніміз не? Кластың жариялануы. Объектінің жариялануы. Кластың синтаксисі.
Кластың өрісі дегеніміз не? Мысалдар. Кластың өрістерінің қалқалануы. Мысалдар.
Кластың әдісі болып не табылады? Мысалдар. Кластың әдісі кәдімгі процедурадан несімен ерекшеленеді?
Әдістердің қалқалануы. Статикалық қалқалану. Динамикалық қалқалану.
Динамикалық, виртуальды және қалқалау әдістері. Мысалдар.
Абстракті әдістер. Мысалдар. Қайта іске қосылатын әдістер.
Конструктор мен деструктор. Мысалдар.
Кластың қасиеті. Қасиеттің синтаксисі. Мысалдар.
Қасиеттің класы өрістің класынан несімен ерекшеленеді? Read, write специфиациялары.
Инкапсуляция. Мысал.
Туындау. Мысал.
Полиморфизм. Мысал.
Кластың құрылымы. Published, private, protected, public секциялары.
Кластарға амадар қолдану. IS және AS кілттік сөздері. Мысалдар.
Оқиға. Оқиғаның сипатталынуының синтаксисі. Мысалдар.
Процедуралық тип. Мысалдар.
Ең қарапайым процедуралық тип болып қандай тип табылады? Sender параметрі.
Оқиғаның өңдегішін қалай шақырады?
Оқиғаға қайта ат тағайындау. Мысалдар.
Өз бетінше орындауға арналған тапсырма
Объектілі – бағытталған бағдарламалаудың негізгі принциптері. Объект, хабарлама, класс, объектінің данасы және әдіс.
Абстракция, инкапсуляция, туындау және полиморфизм. Мысалдар.
Delphi – дің абстрактілі кластарының сипаттамалары (TObject, TPersistent, TComponent).
Delphi – дің абстрактілі кластарының сипаттамалары (TControl, TGraficControl, TWinControl, TScrollingWinControl).
Stored, default (немесе nodefaulte), implements спецификациялары. Мысалдар.
Берілгендердің динамикалық құрылымы. Нұсқағыштар, динамикалық айнымалылар. Мысалдар.
Variant типі. Variant типті айнымалылар. Variants модульі.
Зертханалық жұмыс №4 «Полиморфизм және көрнекілік әдістер»
Полиморфизм — бұл әртүрлі кластарға кіретін әдістерге бірдей ат тағайындау мүмкіндігі. Полиморфизмнің концепциясы Концепция полиморфизма обеспечивает в случае применения метода к объекту использование именно того метода, который соответствует классу объекта.
Біреуі қалған екеуіне базалық класс болатындай үш класс анықталсын:
type
// базалық класс
TPerson = class
FName: String; // өрістің аты
Constructor Create(AName: String);
Function Info: String; virtual;
end;
// TPerson – нан туынды
TStud = class (TPerson)
FGr: Integer; // оқу тобының нөмірі
Constructor Create(Aname: String; Gr: Integer);
Function Info: String; override;
end;
// TPerson – нан туынды
TProf = class(TPerson)
FDep: String; // құжыраның аты
Constructor Create(AName: String; Dep: String);
Function Info: String; override;
end;
Әрбір класта Info әдісі анықталған. Базалық класта virtual директивасының көмегімен Info әдісі көрнекі болып анықталған. Әдістің көрнекі болып анықталуы еншілес класқа көрнекілік әдісті өз меншік әдісімен айырбас жасауға мүмкіндік береді. Әрбір еншілес кластың өзінің Info класы анықталған, ол аталық кластың сәйкес келетін әдісін айырбастайды (аталық кластың көрнекілік әдістерін ауыстыратын туындалған кластың әдісі, override директивасында орналастырылады).
Төменде әрбір класс үшін Info әдісінің анықталуы келтірілген.
function TPerson.Info: String;
begin
result := ' ';
end;
functicn TStud.Info: String;
begin
result := FName + ' группа ' + IntToStr(FGr)
end;
function TProf.Info: String;
begin
result := FName + ' кафедра ' + FDep;
end;
Екі класс та бір базалық кластан туындағандықтан студенттер мен оқытушылардың тізімін былай жариялауға болады (бұл жерде мынаны еске алу қажет, объект дегеніміз - бұл нұсқағыш):
list: array[1..SZL] of TPerson;
Тізімді осылай жариялауға болады, өйткені Object Pascal аталық кластың нұсқағышына еншілес кластың нұсқағышының мәнін меншіктеуге мүмкіндік береді. Сондықтан list массивінің элементі Tstud класының және TProf класының элементтері бола алады.
Студенттер мен оқытушылардың тізімін Info әдісін массив элементтеріне қолдану арқылы шығаруға болады. Мысалы, былай:
st := ' ';
for i := 1 to SZL do // SZL – тізім – массивінің өлшемі
if list[i] <> NIL
then st := st + list[i] .Info + #13;
ShowMessage(st);
Бағдарламаның орындалуы барысында массивтің әрбір элементі TStud типті объектіден де, TProf типті объектіден де тұра алады. Полиморфизмнің коцепциясы объектіге объектінің типіне сай келетін әдісті қолдануды қамтамасыз етеді.
Келесі бағдарлама жоғарыда қарастырылған TPerson, TStud және TProf кластарының жариялануын қолдана отырып, студенттер мен оқытушылардың тізімін қалыптастырады және шығарады. Бағдарламаның мәтіні 2.1 листингісінде, ал қарым – қатынас терезесі сурет 2.1 келтірілген.
Сурет 2.1 «Полиморфизм» бағдарламасының қарым – қатынас терезесі
2.1 листингісі Полиморфизмнің демонстрациясы
Unit polimor_;
Interface
Uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
ТForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
GroupBox1: TGroupBox;
RadioButton1: TRadioButton;
RadioButton2: TRadioButton;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
( Private declarations )
public
( Public declarations )
end;
type
// базалық класс
TPerson = class
FName: String; // өрістің аты
Constructor Create(AName: String);
Function Info: String; virtual;
end;
// Студент класы
TStud = class (TPerson)
FGr: Integer; // оқу тобының нөмірі
Constructor Create(AName: String; Gr: Integer);
Function Info: String; override;
end;
// Оқытушы класы
TProf = class(TPerson)
FDep: String; // құжыраның аты
Constructor Create(AName: String; Dep: String);
Function Info: String; override;
end;
const
SZL = 10; // тізімнің өлшемі
var
Forml: TForml
List: array[1..SZL] of TPerson; // тізім
n: Inteqer = 0 // тізімдегі адамдар саны
implementation
($R *.DFM}
constructor TPerson.Create(AName: string);
begin
FName:=AName;
end;
constructor TStud.Create(AName: string; Gr: integer);
begin
inherited Create(AName); // базалық кластың конструкторын шақыру
FGr:=Gr;
end;
constructor TProf.Create(AName: string; Dep: string);
begin
inherited Create(AName); // базалық кластың конструкторын шақыру
FDep:=Dep;
end;
function TPerson.Info: string;
begin
result:=FName;
end;
function TStud.Info: String;
begin
result := FName + ' группа ' + IntToStr(FGr)
end;
function TProf.Info: String;
begin
result := FName + ' кафедра ' + FDep;
end;
// Добавить батырмасына шерту
procedure ТForm1.Button1Click(Sender: TObject);
begin
if n < SZL then
begin
// объектіні класқа қосу
n:=n+1;
if RadioButton1.Checked
then // TStud объектісін құру
List[n]:=TStud.Create(Edit1.Text,StrToInt(Edit2.Text))
else // TProf объектісін құру
if RadioButton2.Checked then List[nl:=TРrоf.Create(Edit1.Text,Edit2.Text);
// енгізу өрісін тазалау
Edit1.Text :=' ';
Edit2.Text :=' ';
Edit1.SetFocus; // Тышқанның меңзері Фамилия өрісінде
end
else ShowMessage('Список заполнен!');
end;
procedure ТForm1.Button2Click(Sender: TObject);
var
i:integer; // индекс
st:string; // тізім
begin
for i:=1 to SZL do
if list[i] <> NIL then st:=st + list[i].info + #13;
ShowMessage(' Список ' + #13 + st);
end;
end.
Добавить (Button1) батырмасын басқанда іске қосылатын TForm1.Button1Click процедурасы TStud немесе TProf класының list[n] объектісін құрады. Құрылып жатқан объектінің класы RadioButton ауыстырып қосу батырмасының күйімен анықталады. Ауыстырып қосу батырмасының студент (RadioButton1) жағдайында орнатылуы TStud класын анықтайды, ал оқытушы (RadioButton2) жағдайы – TProf класын анықтайды.
Список (Button2) батырмасын басқанда іске қосылатын TForm1.Button2Click процедурасы тізімнің әрбір объектісіне (массив элементтеріне) Info әдісін қолдана отырып,барлық тізімді көрсететін жолды қалыптастырады.
Зертханалық жұмыс №5 "Қаситтер мен әдістер"
Кластың сипатталынуы "Қос мәнді теріс емес бүтін сан" (TN2).
Қасиет – аты, мәні, тақтық, бірінші сан, екінші сан.
Әдістер:
– процедуры: мәнді орнату (SetN2), сандарды ауыстыру (Swap);
– функциялар: басқа санға қарағанда кіші (LessThen), ақпарат (Info);
– конструктор (Create).
Листинг 2.2 «TN2» класын жүзеге асыратын бағдарламаның демонстрациясы
program Class_TN2;
{$APPTYPE CONSOLE} {Компилятор директивасы – бағдарламаның жұмыс істеу режимінің тапсырмасы.}
{MS-DOS режиміне тәріздес мәтіндік режимнің эмуляторы құрылады}
uses SysUtils;
type
TN2 = class
fName: String;
fVal: integer;
constructor Create(aName: String);
procedure Swap;
function Info: String;
function LessThen(aNum: TN2): Boolean;
procedure SetVal(Value:Integer);
function GetOdd:string;
function GetD1:byte;
procedure SetD1(Value:byte);
function GetD2:byte;
procedure SetD2(Value:byte);
property Name:string read fName;
property Odd:string read GetOdd;
property Val:integer read fVal write SetVal;
property D1:byte read GetD1 write SetD1;
property D2:byte read GetD2 write SetD2;
end;
constructor TN2.Create(aName: String);
begin
fName:=aName;
fVal:=1;
end;
procedure TN2.Swap;
begin
SetVal(D2*10+D1);
end;
function TN2.Info: String;
begin
Result:='Naturalnoe dvuznachnoe '+odd+
' chislo '+Name+'='+IntToStr(Val)+#10#13+' first number='
+IntToStr(D1)+' second number='+IntToStr(D2);
end;
procedure TN2.SetVal(Value: Integer);
begin
if (Value>=0) and (Value<=99) then fVal:=Value;
end;
function TN2.LessThen(aNum: TN2): boolean;
begin
Result:= Val
end;
function TN2.GetOdd: string;
begin
if (val mod 2=1) then Result:='nechetnoe'
else Result:='chetnoe';
end;
function TN2.GetD1: byte;
begin
Result:=Val div 10;
end;
procedure TN2.SetD1(Value: byte);
begin
if Value in [0..9] then SetVal(Value*10+D2)
end;
function TN2.GetD2: byte;
begin
Result:=Val mod 10;
end;
procedure TN2.SetD2(Value: byte);
begin
if Value in [0..9] then SetVal(D1*10+Value)
end;
var a,b : TN2;
begin
a:= TN2.Create(' a ');
b:= TN2.Create(' b '); { Бағдарламаның орындалуының нәтижесі
b.Val:= 23; {
Writeln(a.Info); {
Writeln(b.Info); {
b.swap; {
a.D1:= 5; {
a.D2:= 8; {
Writeln(a.Info); {
Writeln(b.Info); {
a.Free; {
b.Free; {
Readln; {
end.
Өз бетінше орындауға арналған тапсырма
Кластың сипатталынуы "Жазықтықтағы нүкте" (TDot).
Қасиеттер – аты, декарттық координаталар, полярлық координаталар,
жазықтықтың нөмірі (егер оське тиісті болса, онда 0-ге тең), оське тиісті ме?
Әдістер:
– процедуралар: басқа нүктеге дейінгі ара қашықтық (RoFrom), векторға көшу (dx,dy) (MoveRel); координаталар басына қарағанда симметриялық бейнелеу (SimmZero), x=y осіне қарағанда симметриялық бейнелеу (SimmXY);
– функциялар: ақпарат (Info);– конструктор (Create).
Зертханалық жұмыс №6 "Оқиғалар"
Кластың сипатталынуы "Кәдімгі бөлшек" (TDrob).
Қасиеттері – аты, мәні, бөлінді және бөлгіш.
Әдістер:
– процедуралар: бөлшекті орынымен ауыстыру (Swap), басқа бөлшектің мәнін қосу (Add);
– функциялар: ақпарат (Info);
– конструктор (Create).
Оқиғалар:
– бөлшек өзгерді (OnChange), стандарттық;
– бөлгіш нөлге тең (OnZero), параметрлері – ескі мән.
2.3 листингі «TDrobs» класының жариялануынан тұратын DROBS модульі
unit Drobs;
interface
uses SysUtils,Classes;
type
TMyEvent=procedure(Sender:TObject;OldP,OldQ:longint) of Object;
TDrob=class
private
fName:string;
fp,fq:longint;
fOnChange:TNotifyEvent;
fOnZero:TMyEvent;
procedure SetP(NewP:longint);
procedure SetQ(NewQ:longint);
public
constructor Create(aName:string);
procedure Swap;
procedure Add(a:TDrob);
function Info:string;
function GetValue:real;
procedure SetValue(NewValue:real);
procedure SetPQ(NewP,NewQ:longint);
property Name:string read fName write fName;
property Value:real read GetValue write SetValue;
property p:longint read fp write SetP;
property q:longint read fq write SetQ;
property OnChange:TNotifyEvent read fOnChange write fOnChange;
property OnZero:TMyEvent read fOnZero write fOnZero;
end;
implementation
procedure TDrob.SetPQ(NewP, NewQ: longint);
var pp,qq : longint;
begin
if (NewP<>p) or (NewQ<>q) then
begin
pp:=p; qq:=q;
if NewQ<>0
then
begin fp:=NewP; fq:=NewQ; Normalization; end
else
begin fp:=NewP; fq:=1;
if assigned(fOnZero) then OnZero(Self,pp,qq)
end;
if assigned(fOnChange) then OnChange(Self);
end;
end;
constructor TDrob.Create;
begin
inherited Create;
Name:=aName;
SetPQ(1,1);
end;
function TDrob.Info: string;
begin
Result:='Дробь '+Name+'= '+IntToStr(p)+'/'+IntToStr(q)+'='+
FloatToStrF(Value,ffFixed,9,5);
end;
procedure TDrob.Swap;
begin
SetPQ(q,p);
end;
procedure TDrob.Add(a: TDrob);
begin
SetPQ(p*a.q+q*a.p,q*a.q);
end;
procedure TDrob.SetP(NewP:longint);
begin
SetPQ(NewP,q);
end;
procedure TDrob.SetQ(NewQ: longint);
begin
SetPQ(p,NewQ);
end;
function TDrob.GetValue: real;
begin
Result:=p/q;
end;
procedure TDrob.SetValue(NewValue: real);
begin
SetPQ(round(NewValue*10000),10000);
end;
end.
Delphi – дегі демонстрациялық бағдарлама
– Drobs модульі қосылады:
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, Drobs;
– екі бөлшекке тағайындалған айнымалылар сипатталынады:
var
Form1 : TForm1;
a,b : TDrob;
– пішінге келесі объектілер орналастырылады:
GroupBox1, GroupBox2
|
бірінші және екінші бөлшектердің демонстрациясы үшін;
|
Label1, Edit1
|
бірінші бөлшектің бөліндісі
|
Label2, Edit2
|
бірінші бөлшектің бөлгіші
|
Label3, Edit3
|
бірінші бөлшектің мәні
|
Label4, Edit4
|
екінші бөлшектің бөліндісі
|
Label5, Edit5
|
екінші бөлшектің бөлгіші
|
Label6, Edit6
|
екінші бөлшектің мәні
|
Button1
|
"Орын ауыстыру"
|
Button2
|
"+"
|
Button3
|
"INFO" бірінші бөлшек үшін
|
Button4
|
"INFO" екінші бөлшек үшін
|
– үш процедура қосылады – бөлшектерді өңдеу үшін:
бірінші бөлшектің өзгеруі:
procedure TForm1.AChange(Sender: TObject);
begin
GroupBox1.Caption:=a.Name;
Edit1.Text:=IntToStr(a.p);
Edit2.Text:=IntToStr(a.q);
Edit3.Text:=FloatToStrF(a.Value,ffFixed,9,5);
end;
екінші бөлшектің өзгеруі:
procedure TForm1.BChange(Sender: TObject);
begin
GroupBox2.Caption:=b.Name;
Edit4.Text:=IntToStr(b.p);
Edit5.Text:=IntToStr(b.q);
Edit6.Text:=FloatToStrF(b.Value,ffFixed,9,5);
end;
екі бөлшек үшін бөлгіштің нольге айналуы:
procedure TForm1.ZeroEvent(Sender: TObject;
OldP,OldQ:longint);
begin
with sender as TDrob do
if MessageDlg('Дробь '+Name+
' получила нулевой знаменатель,'+
' который бы заменен единицей.
Восстановить прежнее значение?',
mtWarning,[mbYes,mbNo],0) = mrYes then SetPQ(OldP,OldQ);
end;
– бөлшектерді басқаруға арналған көрнекілік құрауыштардың өңдеу - процедуралары қосылып жазылады:
Form1.OnCreate оқиғасының өңделуі (пішінді құру):
a:=TDrob.Create('a');
a.OnChange:=AChange; a.OnChange(a);
a.OnZero:=ZeroEvent;
b:=TDrob.Create('b');
b.OnChange:=BChange; b.OnChange(b);
b.OnZero:=ZeroEvent;
бөлінді мен бөлгіштің терезелерінде символдық батырмалардың басылуы
Edit1, Edit2, Edit4, Edit5 құрауыштары үшін OnKeyPress оқиғасы:
var st:string;
begin
with Sender as TEdit do
begin
st:=text;
if Key='-'
then begin
if st[1]='-' then Delete(st,1,1)
else st:='-'+st;
Text:=st;
end;
if not (Key in ['0'..'9',#8]) then Key:=#0;
if Key=#8 then if Length(st)<2 then Key:=#0;
end;
end;
бөлінді мен бөлгіштің өзгеруі
Edit1.OnChange: a.p:=StrToInt(Edit1.Text);
Edit2.OnChange: a.q:=StrToInt(Edit2.Text);
Edit4.OnChange: b.p:=StrToInt(Edit4.Text);
Edit5.OnChange: b.q:=StrToInt(Edit5.Text);
бөлшектің мәнінің өзгеруі ( батырмасын басқанда)
Edit3.OnKeyPress: if Key=#13 then
a.Value:=StrToFloat(edit3.Text);
Edit6.OnKeyPress: if Key=#13 then
b.Value:=StrToFloat(edit6.Text);
"Обмен" батырмасының басылуы
Button1.OnClick: a.Swap;
Button2.OnClick: a.Add(b);
бірінші бөлшектің "INFO" батырмасының үстінен тышқанды жылжыту
Button3.OnMouseMove: Button3.Hint:=a.info;
екінші бөлшектің "INFO" батырмасының үстінен тышқанды жылжыту
Button4.OnMouseMove: Button4.Hint:=b.info;
Өз бетінше орындауға тапсырма
– берілген (TDrob) класына қосу керек:
Қасиеттер:
– Simple, қарапайымдылық (числитель меньше знаменателя), оқуға;
– Changable, өзгертуге рұқсат етіледі, оқу мен жазуға арналған.
Әдістер:
– процедуралар: басқа бөлшекпен"–" (Sub), "*" (Mult), "/" (Div) амалдары; басқа бөлшектің ақпараттық өрістерінің көшірмесін жасайтын - Assign(d:TDrob) процедурасы;
– Compare(d:TDrob) функциясы, ағымды бөлшекті басқа бөлшекпен салыстырады (Self=d, Self>d, Self
Оқиға:
– OnChanging (бөлшек өзгереді), өңдеу – процедурасының интерфейсіде (аналогия бойынша с var Accept: Boolean OnDragOver оқиғасы үшін) буль айнымалысы орналасады, ол жаңа мәннің корректілігін анықтайды: (үнсіздік TRUE, FALSE жағдайында алдыңғы мән қайта қалпына келеді). Берілген мүмкіншілкті қолдана отырып бір бөлшекке модульі бойынша 100-ден аспайтын мән қабылдауға, ал екіншісіне жұп бөлгіш қабылдауға рұқсат етілмейді.
2>
Достарыңызбен бөлісу: |