Texto extraído de um bate-papo por e-mail e no Forum com alunos da turma de Programação Orientada a Objetos II :
Dúvida :
Minha dúvida sobre interfaces e classes abstratas é mais relacionada à utilização/prática das mesmas. Vou pegar como exemplo o seu próprio exemplo da sala... sobre as 2 telas com o user control contendo 3 botões.... O user control seria uma classe que implementa a interface, digamos, Crud (responsável pelas ações dos botões...), certo? Nessa classe, como ela implementa essa interface, ela vai declarar todos os métodos (remover, incluir, etc...) dessa interface, porém não vai implementá-las... apenas declarar, certo? Aí na tela de cadastro de clientes (seu exemplo preferido...rs), essa classe (de clientes) também vai implementar a interface Crud, pois um contrato deve ter pelo menos 2 pessoas que o assinem, certo? E dentro da classe clientes, vai existir um objeto da classe user control... certo? Aí o coitado que tá lá navegando no sistema preenche o bendito formulário e clica, por exemplo, em incluir. Ele está clicando em um botão que está dentro da classe user control..... minha pergunta é: a classe user control tem que chamar o metodo incluir, mas não dela própria.... e sim da classe clientes... ou seja.... a classe user control tem que chamar um método da classe que está instanciando ela... é isso mesmo? eu não programo em C#, mas em C# como que seria feito isso?
outra questão que me surgiu agora: apesar da gente falar que a interface é como um contrato onde pelo menos 2 elementos devem assiná-lo (implementá-lo), isso é regra? Digo, SEMPRE que eu tiver interface, obrigatoriamente eu vou ter que ter pelo menos 2 classes que a implementem? eu sei que na prática, no código, não é regra, porque nada me impede de ter uma interface e que só uma classe a implemente... mas no conceito de interfaces... isso é uma regra?
Agora, voltando um pouco na parte de utilização de interfaces e classes abstratas... no semestre passado, após o professor explicar o que era interface e classe abstrata, da forma como ele explicou, pra mim e acho que pra todos que assistiram essas aulas, ficou na cabeça que a interface é uma gambiarra (um workaround...) pro problema de herança multipla porque uma classe pode implementar várias interfaces, porém só pode extender de uma única outra classe (pelo menos no c#)... foi difícil de engolir isso, mas eu até cheguei a perguntar pra ele em que situações eu devo criar uma classe abstrata ou uma interface... ele não soube me explicar muito bem com algum exemplo prático, mas resumindo, ele disse: "nas linguagens de heranca simples (caso do c#), qdo vc está modelando as classes você tem que ter em mente se essa classe algum dia poderá extender de mais de uma classe... se sim, você cria interfaces e não "gasta" a única herança que você tem.. reserva a única herança que você tem para uma classe que você tem certeza que deve ser abstrata
Minha opinião :
Aqui está o exemplo da Barra.
Agora... sobre a Interface ser uma "gambiarra" para compensar a falta da herança múltipla:
"Muitos vezes o programador é confrontado com o complicado problema de decidir de qualquer classe herdar. Há muitas situações em que seria útil poder herdar de mais de uma classe. Por exemplo, imaginemos que temos uma classe-base que representa leitores de CD, assim como uma outra classe-base que representa leitores de cassetes. De qual classe-base deveria herdar uma classe que represente uma aparelhagem de som ?
Talvez, neste caso fizesse mais sentido utilizar composição (juntar a classe cassete e cd em uma só). No entanto, ao utilizar composição perdemos a capacidade de converter um objeto numa classe-base e utilizá-lo independentemente das suas especificidades.
Para resolver este tipo de problemas, em C# existe o conceito de interface. Uma interface permite obter quase a totalidade dos benefícios da herança múltipla, mas sem os seus problemas. Uma interface espeficifica um conjunto de de métodos que tem que ser implementados por uma classe. Uma classe pode implementar uma ou mais interfaces, bastando para isso indicar quais as interfaces implementadas, tendo os respectivos métodos definidos. As interfaces são extremamente importantes e amplamente utilizadas tanto na plataforma .Net como na programação do dia-a-dia."
Definição do livro C# 2.0
Minha opinião : não entendo como uma gambiarra por conta da falta do recurso da herança múltipla. Entendo sim que é uma característica da plataforma .Net, e por sinal, muito útil.
Outra parte : interface é como um contrato onde pelo menos 2 elementos ?
Como foi bem lembrado na pergunta, o .Net permite que seja uma criada uma interface e que esta interface seja assinada por apenas um único objeto.
Pensando no sentido de Contrato, como as literaturas explicam, um contrato nunca é assinado sozinho. Por exemplo, se você fizer o contrato de compra e venda de uma casa, tanto o vendedor como o comprador assinam o mesmo contrato. Logo, duas assinaturas.
Isso nos leva a sua dúvida. Se duas pessoas assinam um contrato, faria sentido, de forma análoga, que apenas um objeto assinasse a interface ?
Difícil dizer que faz sentido. Eu, por exemplo, não tenho nenhum exemplo prático nos sistemas que desenvolvi que a interface foi assinada por um único objeto.
Porém, um argumento que talvez faça sentido seria o seguinte :
Pense em um objeto que seja responsável pela autenticação de um usuário. Normalmente, em uma aplicação orientada a objetos, esse objeto é único. Vamos supor que, para atender as regras de negócios da sua empresa ou a padrões de segurança, para que um usuário seja autenticado, você deva seguir um conjunto obrigatório de procedimentos.
A utilização da Interface, neste caso, seria uma forma de garantir que o objeto responsável pela autenticação implemente os passos estipulados. Apesar de que, o fato da implementação do método pode não ter "recheio" ( um método vazio) e isso não garantiria que o passo seria executado.
Por outro lado, tornaria a implementação formalizada e, arquiteturalmente falando, tornaria a leitura do código bastante clara.
Desta forma, para mim, faria sentido sim ter uma interface implementada por um único objeto...
Não encontrei literatura que diga de forma explícita que isso seria certo ou errado. Desta forma, infelizmente, preciso embasar a resposta apenas em uma opinião pessoal.
Por fim, falando das classes abstratas, podemos dizer que ela traz consigo as características de uma classe base aliada as características de CONTRATO como acontece com a interface. Porém, como você já herdou uma vez, não poderá ter nova herança na classe-filha.
Nesse momento você pode fazer uma opção. Ao invés de utilizar a classe abstrata, você pode ter na classe-base apenas as operações e propriedades que você tem certeza que serão genéricos e, para operações que você deseja garantir que existam, mas não tem como implementar já na classe-base a operação propriamente dita, você pode utilizar a Interface para fazer o papel do CONTRATO, obrigando a classe-filha a ter o método em questão.
E você, o que acha ?