Дефиниране и внедряване на интерфейси в Delphi

в Delphi, "интерфейс" има две различни значения. в обектно-ориентиран жаргон, можете да мислите за интерфейс като за клас без реализация. В секцията на интерфейса за дефиниране на единица Delphi се използва за деклариране на всички публични секции от код, които се появяват в единица. Тази статия ще обясни интерфейсите от гледна точка на OOP.

Ако сте готови да създадете солидно приложение по начин, който кодът ви да бъде поддържан, многократно използваем и гъвкав, обектно-ориентиран природата на Delphi ще ви помогне да изминете първите 70% от маршрута си. Определянето на интерфейсите и тяхното прилагане ще помогне за останалите 30%.

Абстрактни класове

Можете да мислите за интерфейс като абстрактен клас с премахнато всички изпълнения и премахнато всичко, което не е публично. Абстрактен клас в Delphi е клас, който не може да бъде инстанциран - не можете да създадете обект от клас, обозначен като абстрактен.

Нека да разгледаме примерна декларация за интерфейс:

Тип
IConfigChanged = интерфейс[ '{0D57624C-CDDE-458B-A36C-436AE465B477}']
процедура ApplyConfigChange;
край;
instagram viewer

Най- IConfigChanged е интерфейс. Интерфейсът се дефинира много като клас, ключовата дума „интерфейс“ се използва вместо „клас“. Стойността Guid, която следва ключовата дума на интерфейса, се използва от компилатора за уникално идентифициране на интерфейса. За да генерирате нова GUID стойност, просто натиснете Ctrl + Shift + G в Delphi IDE. Всеки определен от вас интерфейс се нуждае от уникална стойност на Guid.

Интерфейсът в OOP дефинира абстракция - шаблон за действителен клас, който ще реализира интерфейса - който ще приложи методите, дефинирани от интерфейса. Интерфейсът всъщност не прави нищо, той има само подпис за взаимодействие с други (внедряващи) класове или интерфейси.

Реализацията на методите (функции, процедури и свойства Get / Set) се извършва в класа, който реализира интерфейса. В дефиницията на интерфейса няма раздели за обхват (частни, публични, публикувани и т.н.), всичко е публично. Тип интерфейс може да дефинира функции, процедури (които в крайна сметка ще се превърнат в методи от класа, който реализира интерфейса) и свойства. Когато интерфейс дефинира свойство, той трябва да дефинира методите get / set - интерфейсите не могат да определят променливи.

Както при класовете, интерфейсът може да наследи от други интерфейси.

Тип
IConfigChangedMore = интерфейс(IConfigChanged)
процедура ApplyMoreChanges;
край;

Програмиране

Повечето разработчици на Delphi, когато мислят за интерфейси, мислят за COM програмиране. Интерфейсите обаче са само OOP функция на езика - те не са обвързани специално с COM. Интерфейсите могат да бъдат дефинирани и внедрени в приложение на Delphi, без изобщо да докосвате COM.

изпълнение

За да внедрите интерфейс, трябва да добавите името на интерфейса към класовия оператор, както в:

Тип
TMainForm = клас(TForm, IConfigChanged)
обществен
процедура ApplyConfigChange;
край;

В горния код форма на Delphi, наречена "MainForm", реализира интерфейса IConfigChanged.

Внимание: когато клас реализира интерфейс, той трябва да реализира всички свои методи и свойства. Ако не успеете / забравите да приложите метод (например: ApplyConfigChange) грешка във времето за компилиране "E2003 Недеклариран идентификатор: 'ApplyConfigChange'" ще се случи.
Внимание: ако се опитате да укажете интерфейса без GUID стойността, която ще получите: „Тип E2086„ IConfigChanged “все още не е дефиниран напълно“.

пример

Помислете за приложение на MDI, при което на потребителя могат да бъдат показани няколко формуляра наведнъж. Когато потребителят промени конфигурацията на приложението, повечето формуляри трябва да актуализират своя дисплей - показват / скриват някои бутони, актуализират надписи на етикети и т.н. Ще ви трябва прост начин да уведомите всички отворени формуляри, че се е променила конфигурацията на приложението. Идеалният инструмент за работата беше интерфейс.

Всеки формуляр, който трябва да бъде актуализиран, когато промените в конфигурацията ще внедрят IConfigChanged. Тъй като екранът за конфигуриране е показан модално, когато затваря следващия код, гарантира, че всички форми за изпълнение на IConfigChanged са уведомени и се призовава ApplyConfigChange:

процедура DoConfigChange ();
Var
cnt: цяло число;
icc: IConfigChanged;
започвам
за cnt: = 0 да се -1 + Екран. FormCount правя
започвам
ако Поддържа (Екран. Форми [cnt], IConfigChanged, icc) тогава
ICC. ApplyConfigChange;
край;
край;

Подкрепите функция (дефинирано в Sysutils.pas) показва дали даден обект или интерфейс поддържа определен интерфейс. Кодът се повтаря през екрана. Събиране на форми (на обекта TScreen) - всички форми, които се показват в момента в приложението. Ако форма Screen. Форми [CNT] поддържа интерфейса, Supports връща интерфейса за последния параметър на параметъра и връща true.

Следователно, ако формата реализира IConfigChanged, променливата icc може да се използва за извикване на методите на интерфейса, както са реализирани от формата. Имайте предвид, разбира се, че всяка форма може да има собствено различно изпълнение на процедурата ApplyConfigChange.

предците

Всеки клас, който определяте в Delphi, трябва да има прародител. TObject е крайният прародител на всички предмети и компоненти. Горната идея се отнася и за интерфейсите, IInterface е базовият клас за всички интерфейси. IInterface дефинира 3 метода: QueryInterface, _AddRef и _Release.

Това означава, че нашата IConfigChanged също има тези 3 метода, но ние не сме ги приложили. Това е така, защото TForm наследява от TComponent, който вече изпълнява IInterface за вас! Когато искате да внедрите интерфейс в клас, който наследява от TObject, уверете се, че вашият клас наследява вместо TInterfacedObject. Тъй като TInterfacedObject е TObject, изпълняващ IInterface. Например:

TMyClass = клас(TInterfacedObject, IConfigChanged)
процедура ApplyConfigChange;
край;

В заключение, IUnknown = IInterface. Неизвестно е за COM.

instagram story viewer