ПоәК 042-18-11 20. 84/01-2013 №1 баспа 26. 08. 2013 ж


Инкапсуляция, туындау және полиморфизм



жүктеу 2,68 Mb.
бет3/22
Дата29.01.2020
өлшемі2,68 Mb.
#27671
1   2   3   4   5   6   7   8   9   ...   22

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,68 Mb.

Достарыңызбен бөлісу:
1   2   3   4   5   6   7   8   9   ...   22




©g.engime.org 2024
әкімшілігінің қараңыз

    Басты бет
рсетілетін қызмет
халықаралық қаржы
Астана халықаралық
қызмет регламенті
бекіту туралы
туралы ережені
орталығы туралы
субсидиялау мемлекеттік
кеңес туралы
ніндегі кеңес
орталығын басқару
қаржы орталығын
қаржы орталығы
құрамын бекіту
неркәсіптік кешен
міндетті құпия
болуына ерікті
тексерілу мемлекеттік
медициналық тексерілу
құпия медициналық
ерікті анонимді
Бастауыш тәлім
қатысуға жолдамалар
қызметшілері арасындағы
академиялық демалыс
алушыларға академиялық
білім алушыларға
ұйымдарында білім
туралы хабарландыру
конкурс туралы
мемлекеттік қызметшілері
мемлекеттік әкімшілік
органдардың мемлекеттік
мемлекеттік органдардың
барлық мемлекеттік
арналған барлық
орналасуға арналған
лауазымына орналасуға
әкімшілік лауазымына
инфекцияның болуына
жәрдемдесудің белсенді
шараларына қатысуға
саласындағы дайындаушы
ленген қосылған
шегінде бюджетке
салығы шегінде
есептелген қосылған
ұйымдарға есептелген
дайындаушы ұйымдарға
кешен саласындағы
сомасын субсидиялау