Este é um post disponível para assinantes MVPPOO - Dominando o uso de Interfaces - Revista Clube Delphi 134
O artigo trata sobre interfaces, que são contratos estabelecidos para que classes os sigam. No artigo será visto como criar, usar, trocar e delegar interfaces. Também serão vistos erros comuns a se evitar e as novidades do Delphi XE para o trata
[Artigo já está disponível no Leitor Digital DevMedia®. Clique aqui para acessá-lo]
> Clique aqui para ler todos os artigos da ClubeDelphi 134
Interface é uma palavra com múltiplos significados, tanto na física, na comunicação e na ciência da computação. No caso da ciência da computação o termo foi “emprestado” mais de uma vez, pois pode significar o tipo ou padrão de conexão entre dois componentes, o conjunto de elementos gráficos para comunicar um estado ou aceitar comandos de um usuário (GUI) e um contrato ou padrão entre dois objetos ou componentes.
No caso do hardware, por exemplo, USB é uma interface. É possível conectar qualquer tipo de dispositivo na porta USB de um computador contanto que o dispositivo siga certos padrões, ou seja, implemente a interface USB. O mesmo ocorre com PCI, PCI-express e outras tantas portas de conexão do computador.
Não é necessário ir muito longe: o TCP/IP fornece uma linguagem comum, acima dos protocolos físicos como ethernet, para que qualquer dispositivo em uma rede possa se comunicar em uma linguagem comum. O HTTP é um protocolo implementado sobre TCP/IP que recebe e envia dados através de requisições GET e POST e é a base de todas os sistemas online, redes sociais, webservices e computação em nuvem.
Qualquer objeto tem uma interface, mesmo que seja implícita, pois tem um conjunto de métodos e atributos públicos, que são visíveis e podem ser usados ou conectados com o meio exterior. A classe da Listagem 1, com seus métodos e atributos públicos e privados, tem uma interface implícita, que é o conjunto de seus membros públicos.
Nota: Todos os exemplos desse artigo foram feitos em um formulário com vários TButton, um para cada teste, e alguns métodos ou eventos. O código distribuído junto com esta edição tem mais exemplos além dos mostrados no artigo. O objetivo é que o leitor explore esse código modificando ou comentando partes para observar o que acontece.
Listagem 1. Classe de exemplo
TForm1 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;
TUmaClasse = class
private
FUmaData: TDateTime;
FUmNumero: integer;
FUmNome: string;
FUmaFracao: Double;
FUmBooleano: boolean;
procedure UmMetodoPrivado;
property Data: TDateTime read FUmaData write FUmaData;
public
procedure SetNome(const value: string);
function GetNome: string;
procedure DigaAlo;
property
end;
Temos duas classes, um formulário e a classe TUmaClasse. Em TUmaClasse apenas SetNome, GetNome, DigaAlo e Nome são públicos, por isso eles definem uma interface implícita.
Em programação orientada a objetos quando se cria uma interface cria-se um contrato que deve ser respeitado por quem a implementa. A classe que implementa uma interface deve obrigatoriamente ter os métodos dela implementados.
Há uma certa similaridade com classes abstratas, mas a similaridade para por aí. É correto afirmar que uma classe totalmente abstrata não tem nenhum “comportamento” pois todo ele será criado nas classes derivadas, mas ainda assim uma classe derivada pode implementar alguns métodos e deixar outros ainda abstratos, para uma implementação futura. Adicionalmente uma classe abstrata ainda pode ter atributos públicos, ou propriedades, que podem ser herdados pelos seus descendentes. Uma classe totalmente abstrata não pode ser instanciada, mas uma classe que tem alguns métodos abstratos pode.
Além disso quando se começa uma família de classes a partir de uma classe abstrata todos os seus descendentes seguem uma herança linear, vertical. Usando interfaces esse cenário muda muito.
Para interfaces valem todas as regras de herança e polimorfismo, exceto que uma interface pode “herdar” de uma, duas ou mais interfaces. Quando uma interface herda de outra o termo técnico apropriado é “implementa” e não herda. O mesmo ocorre quando uma classe implementa uma interface.
Uma classe não pode ser descendente de uma interface, mas se for descendente de uma classe que implementa uma interface, ela e todos os seus descendentes passam automaticamente pela herança a implementar essa interface também.
"ATENÇÃO! A exibição deste artigo foi interrompida.
Este é um post disponível para assinantes MVP
5 COMENTÁRIOS
Fui tentar fazer exatamente como é mostrado nas listagens apresentadas para exemplos e dá erro quando tento compilar o código da 'listagem 5' da página 49, na seguinte parte:
-> if (aviao is TAviao) then
begin
ShowMessage('Avião é um TAviao');
(aviao as TAviao).DeslocarSe;
end;
O Delphi apresenta a seguinte mensagem de erro:
Operator not applicable to this operand type
Se alguém puder me ajudar me explicando o porquê disso, agradeço.
Qual é a versão do seu Delphi? Algumas particularidades dos operadores "is" e "as" no sentido interface --> objeto passaram a funcionar apenas no Delphi XE.
Além disso a interface deve obrigatoriamente ter um GUID para que os operadores is e as funcionem com ela.
O que você pode fazer é um typecast forçado, tipo:
var
o: TObject;
o := TObject(minhainterface);
//operações com O agora podem usar is e as
mas cuidado: a linha o := TObject(minhainterface) cria uma nova referencia a uma instância já existente que não será contada pelo contador de referencias da interface. Se algum método ou trecho de código atribuir nil à minhainterface zerando o contador de referências a instância será destruida antes da hora e "o" terá uma referência inválida. Faça testes para verificar leaks ou corrupção de memória com o Fast Memory Manager 4 e não use o método Free em "o".
Space do autor


0
0
