Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Интерфейстің құрылуы және пайдаланылуы
Интерфейстер типтерді сипаттаудың дербес жағ дайы. олар interface қ ызметші сө зінің кө мегімен хабарланады. Мысалы,
Type IEdit=interface Procedure Copy; stdcall; Procedure Cut; stdcall; Procedure Paste; stdcall; Function Undo; stdcall; End; Мұ ндағ ы хабарлау абстракт класты сипаттаумен бірдей, яғ ни интерфейсті шақ ыру ондағ ы хабарланғ ан қ асиеттер мен ә дістерді талдауды талап етпейді. Кластардан айырмашылығ ы интерфейстің ө рістері болмайды, сондық тан ондағ ы read жә не write бө лімінде хабарланғ ан қ асиеттер тек ә діске ғ ана сілтеме жасауы мү мкін. Интерфейсте хабарланғ ан барлық мү шелер тек Public секциясында орналасады. Ә дістер абстракт (abstract), виртуалды (virtual), динамикалық (dinamic) немесе жабылатын (override) бола алмайды. Интерфейстерде конструкторлар немесе деструкторлар болмайды, яғ ни ондағ ы сипатталғ ан ә дістер тек оны сү йемелдейтін кластың шең берінде ғ ана жү зеге асырылады, ол интерфейстің аты оның аталық тізіміндегі кластың хабарлануында кө рсетіледі:
TEditor=class(TInterfacedObject, IEdit) Procedure Copy; stdcall; Procedure Cut; stdcall; Procedure Paste; stdcall; Function Undo: Boolean; stdcall; End;
Ә деттегі кластан интерфейстік кластың айырмашылығ ы оның бірнеше аталық интерфейсі болуы мү мкін: Type IMyInterface=interface Procedure Delete; stdcall; TmyEditor=class(TInterfacedObject, IEdit, IMyInterface) Procedure Copy; stdcall; Procedure Cut; stdcall; Procedure Paste; stdcall; Function Undo: Boolean; stdcall; Procedure Delete; stdcall; End;
Кез келген жағ дайдағ ы интерфейстік класты жү зеге асыру бө лімінде сә йкес интерфейстік ә дістерді сипаттау қ ажет. Мысалы, егер интерфейс хабарланғ ан болса IPaint=interface Procedure CirclePaint(Canva: Tcanvas; x, y, R: integer); Procedure RectPaint(Canva: Tcanvas; x1, x2, y1, y2, R: integer); End; Кез келген жағ дайдағ ы интерфейстік класты жү зеге асыру бө лімінде сә йкес интерфейстік ә дістерді сипаттау қ ажет. Мысалы, егер интерфейс хабарланғ ан болса
IPaint=interface ProcedureCirclePaint(Canva: Tcanvas; x, y, R: integer); Procedure RectPaint(Canva: Tcanvas; x1, x2, y1, y2, R: integer); End; жә не оның интерфейстік класын пайдаланатын болса, TPainter=class(TInterfaceObject, Ipaint) ProcedureCirclePaint(Canva: Tcanvas; x, y, R: integer); Procedure RectPaint(Canva: Tcanvas; x1, x2, y1, y2, R: integer); End; онда implementation бө лімінде ә дістің жү зеге асырылуын кө рсету қ ажет: Procedure Tpainter.CirclePaint(Canva: TCanvas; x, y, R: integer); begin With Canva do Ellipse(x, y, x+2*R, y+2*R); End; Procedure Tpainter.CirclePaint(Canva: TCanvas; x1, y1, x2, y2, R: integer); begin With Canva do Rectabgle(x1, y1, x2, y2); End; Енді шең бер жә не квадрат сызу ү шін кластың интерфейстік объектісін хабарлауғ а болады: Procedure Tform1.PaintBoxPaint(Sender: TObject); var Painter: IPaint; begin Painter: =TPainter.Create; Painter.CirclePaint(PaintBox1.Canvas, 10, 0, 10); Painter.RectPaint(PaintBox1.Canvas, 40, 0, 60, 20); End; Интерфейс оның пайдаланатын интерфейстік класын хабарлағ анғ а дейін хабарланатындығ ын қ арамастан, оның ә дістерінің кластың хабарлауында келтірілетіні міндетті екені компиляторғ а белгілі. Біздің жағ дайда оны былай кө рсетуге болады: Type TPainter=class(TInterfaceObject, IPaint) End; Мұ нда жазу қ ате болар еді: компилятор CirclePaint жә не RectPaint ә дістерінің сипатталуын қ оюды талап етер еді. Сондай-ақ, Object Pascal тілінің барлық кластары жалғ ыз аталық класс Tobject класынан туындағ аны тә різді барлық интерфейстік кластар TinterObject жалпы аталығ ынан туындағ ан. Бұ л аталық жадыны интерфейстік объектілер ү шін ү лестіре алады жә не Iunknow глобальды интерфейсін пайдаланады: Type TinterfacedObject=class(TObject, IUnknown) Private Frefcount: integer; Protected Function QueryInterface(constIID: TGUID; outObj): integer; stdcall; Function_AddRef: integer; stdcall; Function_Relefse: integer; stdcall; Public Property RefCount: integer read FrefCount; End; Егер алдың ғ ы мысалда Tpainter класы тө мендегідей сипатталғ ан болса: TPainter=class(TPaint) ProcedureCirclePaint(Canva: Tcanvas; x, y, R: integer); Procedure RectPaint(Canva: Tcanvas; x1, x2, y1, y2, R: integer); End; Онда компилятор TinterfaceObject класының QueryInterface_Add_Release ә дістерін қ осуды талап етер еді. Бұ л кластың FrefCount ө рісі интерфейстік объектіні шақ ыру есептегішінің қ ызметін атқ арады жә не Windows схемасында қ абылданғ анындай пайдаланылады: Iunknow интерфейсінің Add ә дісіне ә рбір оралғ ан сайын есептегіш 1-ге артады, ал Release ә дісіне оралғ ан сайын есептегіш 1-ге кемиді. Бұ л ө рістің мә ні нольге тең болғ анда интерфейстік объект жойылып, жадыдан алғ ан орнын босатады. Интерфейстік объектіге as типтерді келтіру операторын қ олдануғ а болады, бұ л жағ дайда керекті интерфейс таң далады: Procedure PaintObject(P: TInterfacedObject) Var x: IPaint begin Try X: PasIPaint; X.CirclePaint(PaintBox1.Canvas, 0, 0, 20) Except ShowMessage('объект IPaint интерфейсін сү йемелдемейді') End; end; Мұ ндай меншіктеуді кездестіргеннен кейін компилятор код қ ұ рады жә не оның кө мегімен Ipaint интерфейсіне сілтеме жасауды шақ ырылады. Егер объект кө рсетілген интерфейсті сү йемелдемейтін болса, шектен тыс жағ дай пайда болады. қ ашық тық тағ ы объектіні пайдалануғ а есептелген интерфейстер глобальды бірегей идентификатормен жабдық талуы тиіс (Guid). Мысалы, IPaint=interface ['{AYAFEB60-7705-11D2-8B-41-4444553540000}'] ProcedureCirclePaint(Canva: TCanvas; x, y, R: integer); ProcedureRectPaint(Canva: TCanvas; x1, y1, x2, y2: integer); End; Implements қ ызметші сө зінің кө мегімен программист кейбір класқ а қ андай да бір қ асиетті қ оса алады. Бұ л қ асиеттің типі интерфейс немесе класс болуы мү мкін. Егер қ асиеттің типі интерфейс болса, бұ л интерфейстің аты аталық кластар тізімінде кө рсетілуі тиіс, яғ ни интерфейстік кластағ ыдай: Type IMyInterface=interface Procedure P1; Procedure P2; End; TMyClass=class(TObject, IMyInterface) IMyInterface=IMyInterface; Property MyInterface: IMyInterface Read FMyInterface implements ImyInterface; End; Мұ нда мына мә селеге кө ң іл аудару қ ажет: мысалдағ ы TmyClass интерфейстік класс болып табылмайды, яғ ни Р1 жә не Р2 ә дістері орындалатын класс. Егер одан MyInterface ө кілетті қ асиетін анық тауды алып тастаса, онда ол интерфейстік болып табылады жә не MyInterface ә дісін сипаттау қ ажет. Ө кілетті қ асиетте міндетті тү рде read болуы тиіс. Егер оның типі класс болса жә не ол сол хабарланғ ан болса, оның басқ а ө кілетті қ асеиттерінің болуы мү мкін емес.
|