DevMedia
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Este é um post disponível para assinantes MVP
Este post também está disponível para assinantes da ClubeDelphi DIGITAL
ou para quem possui Créditos DevMedia.

Clique aqui para saber como acessar este post

1) Torne-se um assinante MVP e por apenas R$ 69,90 por mês você terá acesso completo a todos os posts. Assinar MVP

2) Adquira Créditos: comprando R$ 180,00 em créditos esse post custará R$ 1,20. Comprar Créditos

ClubeDelphi 134 - Índice

POO - 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 tratamento de interfaces.

[fechar]

Você não gostou da qualidade deste conteúdo?

(opcional) Você poderia comentar o que não lhe agradou?

Confirmo meu voto negativo

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 Nome: string read GetNome write SetNome;

  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.

Como múltiplas interfaces podem ser implementadas por uma classe ou interface é possível usar esse mecanismo para simular herança múltipla, fazendo com que todos os métodos de várias interfaces se combinem em uma única. Se a implementação das interfaces forem delegadas a objetos que já as implementem então tem-se herança múltipla “quase real” e com pouquíssimas linhas de código.

Um outro grande benefício das interfaces é que elas tem uma contagem de referências interna. Isso significa que elas não precisam ser destruídas, pois se auto destroem quando nenhum outro objeto precisa delas. Isso é o mais próximo que temos de um garbage collector.

Quando se programa orientado a interfaces automaticamente protege-se o software de uma dependência mútua de detalhes de implementação. Isso é um reforço para o conceito de encapsulamento, ou “caixa preta”, pois um objeto que implementa uma interface pode ser substituído por qualquer outro que também implemente essa interface sem que o código pare de funcionar, mesmo que o comportamento do outro objeto seja totalmente diferente. Ou seja, se um objeto A implementa uma interface sua implementação deve ser isolada de qualquer objeto B que dependa (seja cliente, use) A. Desse modo, B usa apenas a interface de A, e qualquer alteração em A ou B pode ser feita contanto que esse contrato continue sendo respeitado.

No Windows, componentes DCOM, COM, COM+ e ActiveX implementam interfaces. A programação usando essa parte da API do Windows inevitavelmente usa ou implementa uma interface. Isso foi feito dessa maneira no Windows para que desenvolvedores pudessem criar, além de programas, extensões, plugins, complementos e suplementos para o próprio Windows, e também para o Word, Internet Explorer e assim por diante. Para isso, a partir da versão 3 do Delphi a linguagem mudou um pouco a hierarquia de interfaces para ser compatível com as interfaces COM do Windows. Pelo mesmo motivo a partir da versão 3 o Delphi passou a suportar implementação múltipla e GUIDs. Nas versões 1 e 2 isso era impossível.

 

Nota do DevMan

O COM (Component Object Model) é uma tecnologia projetada pela Microsoft que atua tanto como especificação quanto implementação. Ela define como componentes e aplicações se comunicam, através de interfaces, e é a base para muitas outras tecnologias, tais como DCOM, MTS, ActiveX, e COM+. As tecnologias precursoras do COM+ foram o DCOM e o MTS. O DCOM permite distribuir objetos em uma rede, além de separar as regras de negócio em uma camada independente da aplicação cliente. O problema do DCOM é a escalabilidade. Ele não apresenta os mesmos resultados quando há um aumento do número de conexões, perdendo desempenho.

O MTS (Microsoft Transaction Server) incorporou diversos recursos ao DCOM. Um problema do DCOM era não possuir um gerenciador próprio. O MTS resolve o problema, fornecendo um gerenciador baseado no MMC (Microsoft Management Console), no qual  podem ser configurados objetos e inúmeras opções.

O COM+ incorpora e estende o DCOM e o MTS e inclui o MSMQ (Microsoft Message Queue), herdando inúmeros recursos. As principais características do COM+ são gerenciamento, transações, escalabilidade, pooling e independência.

 

Ao escrever programas que suportem plugins considera-se o uso de interfaces, pois para escrever plugins para programas já existentes o conhecimento de interfaces é praticamente obrigatório.

É necessário perceber que o conceito de Interfaces, embora muito importante na programação orientada a objetos, não limita-se apenas às linguagens que suportam POO. Em um nível mais amplo, mais abstrato, interfaces são qualquer conjunto de métodos que um componente de software deve implementar para que seja compatível ou que possa trocar informações com outros componentes de software. Mesmo que esses métodos sejam estáticos, públicos e globais, como no caso da API do Windows, ainda persiste a ideia de “contrato”. A própria sigla API é Application Programming Interface.

Geralmente APIs ou bibliotecas de classes e frameworks que contém interfaces têm manuais ou listas de interfaces que devem ser implementadas para garantir certas compatibilidades.

Interfaces devem ser vistas como o conjunto de dentes de uma engrenagem, os furos e pinos de peças de Lego ou ainda do conjunto de palavras e regras de uma linguagem humana.

Uma definição interessante para interfaces é que elas permitem você “interfacear” (neologismo horrível, reconheçamos) duas classes que não tem nada em comum. Por exemplo  pode-se, em um formulário criado dinamicamente, definir uma interface em comum entre todos os tipos de componentes para se executar um mesmo método, ou obter uma mesma propriedade, em todos eles. Exemplos práticos de como fazer isso serão vistos mais adiante.

Interfaces no Delphi

Historicamente o conceito de interfaces vem da linguagem C, onde num arquivo de cabeçalho .h eram colocados as assinaturas, ou protótipos, dos métodos, mas os mesmos eram implementados apenas nos arquivos de código fonte .c.

O Delphi também “herdou” esse conceito do Pascal e do C. Em uma unit há duas seções principais, uma seção interface, onde coloca-se apenas os cabeçalhos ou protótipos das procedures e functions e a seção implementation onde coloca-se a implementação dos mesmos. As units, com suas seções de interface e implementação, eram o mais próximo que o Pascal podia chegar da POO numa época em que ele ainda não tinha efetivamente implementado todas as características e requisitos da POO.

"

A exibição deste artigo foi interrompida

Este post está disponível para assinantes MVP.



Analista de Sistemas Sr. na Editora Revista dos Tribunais. Trabalha com Delphi desde a versão 3. Formado em Processamento de Dados pela FATEC-SP

O que você achou deste post?
Serviços

Mais posts