30 de agosto de 2009

Usando Interfaces em Delphi

Outro dia, estava comentando o uso do Design Pattern Prototype aqui no blog e para implementar o exemplo utilizei uma interface em Delphi. Por causa disso, algumas pessoas me perguntaram o que vem a ser esta tal de interface. Como vou utilizar o conceito para avançar no assunto "Delphi interagindo com scripts", achei melhor postar antes a respeito das interfaces.

Neste contexto, interface não tem nada a ver com telas de um programa ou partes do hardware mas sim com um recurso que algumas linguagens de programação - como Java e, mais recentemente, o Delphi - disponibilizam para tornar mais limpo o código do programa, que de outra forma teria que ser escrito usando heranças múltiplas (uma classe herdando de mais de uma classe base). Além do mais, Delphi e Java não suportam herança múltipla.

Uma interface pode ser encarada como um contrato que tem que ser respeitado. Esse contrato é descrito em termos de métodos e/ou funções que devem ser esperados. Então, ao criar uma nova Classe você pode declará-la como implementadora de uma (ou mais) interface. Isto obriga a nova classe a respeitar fielmente o contrato, ou seja, ela terá obrigatoriamente que providenciar codificação para todas as funções e métodos declarados na interface, inclusive respeitando suas assinaturas - isto é, a quantidade e os tipo dos parâmetros e, no caso de funções, o tipo de dado retornado. Em outras palavras, as Interfaces definem comportamento e as Classes implementam esse comportamento.

E, qual a utilidade disso ? Você poderá criar classes genéricas que façam uso das funções declaradas por uma interface e, então, qualquer classe que implementar a tal interface poderá se beneficiar da classe que a manipula. Um exemplo clássico desse conceito é a criação de uma classe genérica para ordenação. Tudo que é preciso fazer é declarar uma interface com uma função para comparar 2 valores; a classe de ordenação deve manter uma lista com os objetos a serem ordenados e usar a função de comparação para determinar a ordem correta de todos os elementos. Com isso, é possível ordenar listas de objetos de qualquer classe que implemente a interface de ordenação.

Em termos da linguagem de programação, a declaração de uma interface é muito parecida com a declaração de classes. Basicamente, é composto por um nome, a palavra chave interface, uma lista de métodos e/ou funções e end para encerrar. Segue como exemplo a declaração de uma interface para ordenação:
IWSortable = interface
function CompareTo (Elemen: TInterfacedObject): Integer;
end;
Para uma classe dizer que implementa uma determinada interface, usa-se sintaxe semelhante à da herança. No exemplo abaixo, a classe TWPessoa declara que faz uma implementação da interface IWSortable:
TWPessoa = class(TInterfacedObject, IWSortable)
public
Nome : String;
Idade : Integer;
function CompareTo (AElemen: TInterfacedObject) : Integer;
end;
Em Delphi, todas as interfaces são herança de uma mesma interface base chamada IUnknown, o que exige a implementação de alguns métodos. A classe TInterfacedObject do Delphi já faz essa implementação e é por isso que a utilizo como base para TWPessoa. Se fosse necessário incluir outras interfaces na classe TWPessoa, elas deveriam vir separadas por vírgula após o nome da classe pai.

Alguns fatos sobre as interfaces:
Todos os métodos e funções declarados numa interface tem visibilidade public. Por isso, não é permitido incluir nenhuma das declarações de visibilidade e informá-las ocasionará um erro de compilação.
Os métodos e funções de uma interface são sempre abstract e virtual. Portanto, ambas as diretivas são dispensáveis na declaração da interface. Informá-las ocasionará um erro de compilação.
Não é permitido incluir campos numa interface. Propriedadades, no entanto, são admitidas desde que as cláusulas read e write façam referência a funções e métodos.
Uma classe pode implementar quantas interfaces forem necessárias.
É permitido criar heranças de interfaces.


3 comentários :

Ze disse...

Fernando Queiroz :
Como fica a questão de Eventos nas interfaces. É possivel implementar algo assim da mesma forma que é feito no ActiveX? []´s e parabens pelo Blog, muito util!

Gustavo Fabbro disse...

Fernando

Neste post eu falei de Interface como um recurso da linguagem Delphi, desvinculado do assunto ActiveX. O desenvolvimento do ActiveX (COM) foi calcado no conceito de interfaces mas o Delphi permite utilizar as interfaces sem que isso implique em uso do COM (veja o post neste link).
Há no blog outros posts envolvendo interfaces e COM mas ainda não postei nada sobre eventos nessa tecnologia. Devo fazer isso em breve.

Anônimo disse...

Sinceramente, esse negócio de interface não entra na minha cabeça. Não consigo encontar no desenrrolar dos trabalhos fazer o uso de interface.

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.