Definindo e implementando interfaces no Delphi

Dentro Delphi, "interface" tem dois significados distintos. Dentro OOP jargão, você pode pensar em uma interface como uma classe sem implementação. No Delphi, a seção de interface de definição de unidade é usada para declarar qualquer seção pública de código que apareça em uma unidade. Este artigo irá explicar interfaces de uma perspectiva OOP.

Se você deseja criar um aplicativo sólido, de maneira que seu código seja sustentável, reutilizável e flexível, OOP A natureza do Delphi irá ajudá-lo a dirigir os primeiros 70% do seu percurso. Definir interfaces e implementá-las ajudará com os 30% restantes.

Classes abstratas

Você pode pensar em uma interface como uma classe abstrata com toda a implementação removida e tudo o que não é público removido. Uma classe abstrata em Delphi é uma classe que não pode ser instanciada - você não pode criar um objeto a partir de uma classe marcada como abstrata.

Vamos dar uma olhada em um exemplo de declaração de interface:

tipo
IConfigChanged = interface['{0D57624C-CDDE-458B-A36C-436AE465B477}']
procedimento ApplyConfigChange;
fim;
instagram viewer

o IConfigChanged é uma interface. Uma interface é definida como uma classe, a palavra-chave "interface" é usada em vez de "classe". O valor Guid que segue a palavra-chave da interface é usado pelo compilador para identificar exclusivamente a interface. Para gerar um novo valor GUID, basta pressionar Ctrl + Shift + G no Delphi IDE. Cada interface que você define precisa de um valor Guid exclusivo.

Uma interface no OOP define uma abstração - um modelo para uma classe real que implementará a interface - que implementará os métodos definidos pela interface. Na verdade, uma interface não faz nada, apenas possui uma assinatura para interação com outras classes (interfaces) (de implementação).

A implementação dos métodos (funções, procedimentos e métodos Get / Set da propriedade) é feita na classe que implementa a interface. Na definição da interface, não há seções de escopo (privadas, públicas, publicadas etc.), tudo é público. Um tipo de interface pode definir funções, procedimentos (que eventualmente se tornarão métodos da classe que implementa a interface) e propriedades. Quando uma interface define uma propriedade, ela deve definir os métodos get / set - as interfaces não podem definir variáveis.

Como nas classes, uma interface pode herdar de outras interfaces.

tipo
IConfigChangedMore = interface(IConfigChanged)
procedimento ApplyMoreChanges;
fim;

Programação

A maioria dos desenvolvedores Delphi, quando pensam em interfaces, pensam em programação COM. No entanto, as interfaces são apenas um recurso OOP do idioma - elas não estão vinculadas ao COM especificamente. As interfaces podem ser definidas e implementadas em um aplicativo Delphi sem tocar em COM.

Implementação

Para implementar uma interface, você precisa adicionar o nome da interface à instrução de classe, como em:

tipo
TMainForm = classe(TForm, IConfigChanged)
público
procedimento ApplyConfigChange;
fim;

No código acima, um formulário Delphi chamado "MainForm" implementa a interface IConfigChanged.

Atenção: quando uma classe implementa uma interface, ela deve implementar todos os seus métodos e propriedades. Se você falhar / esquecer de implementar um método (por exemplo: ApplyConfigChange), um erro de tempo de compilação "E2003 Identificador não declarado: 'ApplyConfigChange'" Vai acontecer.
Atenção: se você tentar especificar a interface sem o valor GUID, receberá: "O tipo E2086 'IConfigChanged' ainda não está completamente definido".

Exemplo

Considere um aplicativo MDI em que vários formulários possam ser exibidos ao usuário ao mesmo tempo. Quando o usuário altera a configuração do aplicativo, a maioria dos formulários precisa atualizar sua exibição - mostrar / ocultar alguns botões, atualizar legendas de etiquetas etc. Você precisaria de uma maneira simples de notificar todos os formulários abertos que uma alteração na configuração do aplicativo ocorreu. A ferramenta ideal para o trabalho era uma interface.

Todos os formulários que precisam ser atualizados quando as alterações na configuração implementam IConfigChanged. Como a tela de configuração é exibida modalmente, quando ele fecha o próximo código, todos os formulários de implementação IConfigChanged são notificados e o ApplyConfigChange é chamado:

procedimento DoConfigChange ();
var
cnt: inteiro;
icc: IConfigChanged;
início
para cnt: = 0 para -1 + Tela. FormCount Faz
início
E se Suporta (tela. Formulários [cnt], IConfigChanged, icc) então
icc. ApplyConfigChange;
fim;
fim;

Os suportes função (definido em Sysutils.pas) indica se um determinado objeto ou interface suporta uma interface especificada. O código itera pela tela. Coleção de formulários (do objeto TScreen) - todos os formulários atualmente exibidos no aplicativo. Se um formulário Tela. Formulários [cnt] suporta a interface, Supports retorna a interface para o último parâmetro parâmetro e retorna true.

Portanto, se o formulário implementar o IConfigChanged, a variável icc poderá ser usada para chamar os métodos da interface implementados pelo formulário. Observe, é claro, que todos os formulários podem ter sua própria implementação diferente do procedimento ApplyConfigChange.

Antepassados

Qualquer classe que você definir no Delphi precisa ter um ancestral. O TObject é o ancestral final de todos os objetos e componentes. A idéia acima também se aplica às interfaces, o IInterface é a classe base para todas as interfaces. IInterface define três métodos: QueryInterface, _AddRef e _Release.

Isso significa que nosso IConfigChanged também possui esses 3 métodos, mas não os implementamos. Isso ocorre porque o TForm herda do TComponent que já implementa o IInterface para você! Quando você deseja implementar uma interface em uma classe que herda de TObject, verifique se sua classe é herdada de TInterfacedObject. Como TInterfacedObject é um TObject implementando IInterface. Por exemplo:

TMyClass = classe(TInterfacedObject, IConfigChanged)
procedimento ApplyConfigChange;
fim;

Em conclusão, IUnknown = IInterface. IUnknown é para COM.