Uma das dúvidas que mais assolam os
desenvolvedores que estão migrando para ambientes Orientados a Objetos é, com
certeza, o trabalho correto e efetivo com Interfaces. Esta dúvida é
frequentemente encontrada por uma razão em especial: o trabalho com interfaces
requer um alto nível de abstração. Por inércia, desenvolvedores que não
conseguem entender corretamente o funcionamento dessas estruturas acabam
privando-se de sua utilização e, por consequência, desprezando um dos mais
poderosos recursos da orientação a objetos.
Este artigo tem como objetivo principal
tentar ajudar desenvolvedores que possuem dificuldades para trabalhar com
Interfaces, Classes e Métodos Abastratos no C#.
Entendendo Interfaces
O mecanismo de herança entre classes
disponibilizado pelo C# e por outras linguagens de programação é um dos
recursos mais poderosos da O.O., entrentanto, não é mais poderoso que a herança
de interfaces.
Interface é uma estrutura que permite ao
desenvolvedor especificar todos os métodos e propriedades que ele deseja que as
classes que a implementam disponibilizem.
Utilizando uma interface, é possível
separar completamente a definição/assinatura de métodos de suas respectivas
implementações, ou seja, de um lado (interface) temos a definição dos mesmos e
do outro (classe que implementa a interface), temos a implementação dos mesmos.
Podemos entender uma interface como
sendo uma espécie de contrato, ou seja, se uma classe X implementa uma
interface Y, logo, Y garante que X disponibilizará todos os métodos definidos
em Y. Caso este “contrato” seja quebrado, um erro será gerado.
Interfaces são muito importantes pois,
nos permitem separar o “o que” do “como”. A interface não se preocupa com a
forma com a qual o método está sendo implementado e sim, que este método estará
disponível a todos os objetos que a implementarem. A interface descreve a
maneira como você deseja que o objeto seja utilizado ao invés da forma como ele
foi implementado.
Outra importante justificativa para a
utilização de interfaces em seus projetos .NET, é que, assim como o Java, o C#
não trabalha com herança múltipla entre classes de forma nativa. Implementar
este recurso somente é possível através da utilização de interfaces. Em um
artigo futuro, abordaremos esse tema.
Sintaxe da Interface no C#
O trabalho com interfaces no C# é
simples e segue a estrutura apresentada na Listagem 1:
interface ILogger
{
bool gravaLogAutenticacao(string sql);
}
Listagem 1:
Sintaxe para o trabalho com Interfaces no C#
Algumas observações sobre esta
estrtutura são pertinentes. Ao definir-se um método dentro de uma interface,
não devem ser utilizados os modificadores (public, private, ou protected) e,
além disso, o corpo do método é substituído por ; (ponto e vírgula). A lista
abaixo apresenta algumas restrições quanto a utilização das interfaces no C#.
Há uma recomendação na documentação da .NET Framework para que, ao se nomear
uma nova interface a primeira letra do nome seja um I (i maiúsculo). Na Listagem
1, esta recomendação foi seguida ao nomear-se a interface como ILogger.
- O desenvolvedor não tem permissão
para definir campos em uma interface, nem mesmo campos estáticos, pois, um
campo é um detalhe intrínseco de implementação de uma classe ou estrutura.
- O desenvolvedor não possui
permissão para definir construtores e destrutores pelo mesmo motivo
apresentado no ítem 1.
- Modificadores de acesso não podem
ser implementados para métodos de interfaces, pois, implicitamente todos
os elementos em uma interface são públicos.
- Não é possível trabalhar com
estruturas aninhadas: enumeradores, estruturas, etc.
- Interfaces podem herdar apenas
outras interfaces.
Implementando Interfaces
Para implementar uma interface, você
deve criar uma classe ou estrutura de modo que esta herde a interface criada e
implemente todos os métodos nela definidos (lembre-se, o contrato não deve ser
quebrado). Assim, levando-se em consideração o exemplo da interface ILogger
apresentado na Listagem 1, segue um exemplo de uma classe que implementa esta
interface na Listagem 2:
public class
AutenticacaoUsuarios : ILogger
{
bool ILogger.gravaLogAutenticacao(string
sentencaGravacao)
{
//Efetua rotina de gravação
}
}
Listagem 2:
Classe que implementa a interface ILogger
Ao implementar-mos uma interface, temos
que tomar os seguintes cuidados:
- O nome do método e o tipo de
retorno devem corresponder extamente.
- Quaisquer parâmetros, incluindo
modificadores de palavras chave ref e out, tem que equivaler
exatamente.
- É uma boa prática se declarar
explicitamente o método com o nome da interface.
- Todos os métodos que implementam a
interface devem ser publicamente acessíveis.
Bom pessoal, espero que este artigo
possa o ajudar a começar a considerar a utilização de interfaces em seus
projetos. Com o tempo, você perceberá que seu código estará extremamente
estruturado e extensível, aumentando o desacoplamento e baixando o tempo de
manutenção de código.