В официальной документации говорится, что они дополнительные. Я знаю взаимодействующий с COM, требует уникального идентификатора для каждого интерфейса, но каждый интерфейсный пример, который я вижу, имеет GUID, используется ли он с COM или нет? Там какое-либо преимущество к включению GUID если не попытка использоваться с COM?
Я заметил, что некоторые методы, такие как Supports
(для определения соответствия класса определенному интерфейсу), требуют, чтобы вы определили GUID, прежде чем вы сможете их использовать.
Эта страница подтверждает это следующей информацией:
Примечание: Блок SysUtils предоставляет перегруженную функцию под названием Supports которая возвращает true или false, когда класс типы и экземпляры поддерживают определенный интерфейс, представленный GUID. Функция Supports используется в по аналогии с операторами Delphi is и as операторы. Существенное отличие заключается в том, что функция Supports может принимать в качестве правого операнда либо GUID, либо тип интерфейса, ассоциированный с GUID, тогда как is и as принимают имя типа. Для получения дополнительной информации о is и as см. в разделе Ссылки на классы.
Вот интересная информация об интерфейсах, которая гласит:
Почему интерфейс должен быть уникально идентифицируемым? Ответ прост: потому что классы Delphi могут реализовывать несколько интерфейсов. Когда приложение работает, должен быть быть механизм, который будет получать указатель на соответствующий интерфейс из реализации. Единственный способ узнать. узнать, реализует ли объект интерфейс и получить указатель на реализацию этого интерфейса через GUID.
Подчеркивание добавлено в обеих цитатах.
Читая эту статью целиком, вы также понимаете, что QueryInterface
(который требует GUID) используется за кулисами по таким причинам, как подсчет ссылок.
Только если вам нужно, чтобы ваш интерфейс был совместим с COM.
К сожалению, это также включает использование операторов is
, as
и функций QueryInterface
, Supports
- отсутствие которых довольно ограничивает возможности. Поэтому, хотя это и не является обязательным, вероятно, проще использовать GUID. В противном случае вы останетесь только с довольно упрощенным использованием:
type
ITest = interface
procedure Test;
end;
ITest2 = interface(ITest)
procedure Test2;
end;
TTest = class(TInterfacedObject, ITest, ITest2)
public
procedure Test;
procedure Test2;
end;
procedure TTest.Test;
begin
Writeln('Test');
end;
procedure TTest.Test2;
begin
Writeln('Test2');
end;
procedure DoTest(const Test: ITest);
begin
Test.Test;
end;
procedure DoTest2(const Test: ITest2);
begin
Test.Test;
Test.Test2;
end;
procedure Main;
var
Test: ITest;
Test2: ITest2;
begin
Test := TTest.Create;
DoTest(Test);
Test := nil;
Test2 := TTest.Create;
DoTest(Test2);
DoTest2(Test2);
end;