Como saberei quando criar uma interface?


196

Estou em um ponto do aprendizado de desenvolvimento em que sinto que devo aprender mais sobre interfaces.

Eu frequentemente leio sobre eles, mas parece que não consigo entendê-los.

Eu li exemplos como: Classe base animal, com interface IAnimal para coisas como 'Walk', 'Run', 'GetLegs', etc. - mas nunca trabalhei em algo e senti como "Ei, eu devo usar uma interface aqui!"

o que estou perdendo? Por que é um conceito tão difícil para eu entender! Estou apenas intimidado pelo fato de nunca ter percebido uma necessidade concreta de uma - principalmente devido a algum aspecto ausente de compreendê-las! Isso me faz sentir como se estivesse perdendo algo no topo em termos de ser um desenvolvedor! Se alguém teve uma experiência como essa e teve um avanço, eu apreciaria algumas dicas sobre como entender esse conceito. Obrigado.


Respostas:


151

resolve este problema concreto:

você tem a, b, c, d de 4 tipos diferentes. em todo o seu código, você tem algo como:

a.Process();
b.Process();
c.Process();
d.Process();

por que eles não implementam IProcessable e, em seguida,

List<IProcessable> list;

foreach(IProcessable p in list)
    p.Process();

isso aumentará muito quando você adicionar, digamos, 50 tipos de classes que todos fazem a mesma coisa.


Outro problema concreto:

Você já deu uma olhada no System.Linq.Enumerable? Ele define vários métodos de extensão que operam em qualquer tipo que implemente IEnumerable. Como qualquer coisa que implemente o IEnumerable basicamente diz "Suporte a iteração em um padrão não ordenado de tipo foreach", você pode definir comportamentos complexos (Contagem, Máx, Onde, Selecionar etc.) para qualquer tipo enumerável.


2
Isso ajuda. Qual é a vantagem de ter uma interface presente, em vez de apenas os tipos terem implementação para o método Process ()?
user53885

Você não seria capaz de usar a mesma variável p, a menos que todas fossem subclasses do mesmo tipo base ou implementassem a interface.
Karl

Você não precisa converter, ao contrário de 50 classes diferentes com um método Process. O C # não usa "digitação de pato"; portanto, apenas porque A possui Process () e B possui Process () também não significa que existe uma maneira genérica de chamar. Você precisa de uma interface para isso.
user7116

certo. Acabei de alterar "var" para "IProcessable" para que o exemplo faça mais sentido.
Jimmy Jimmy

2
@ Rogerio: Eu estava tentando ser genérico. O ponto não é que "quando você tem coisas que possuem uma função Process ()" é "quando você tem coisas que compartilham um conjunto comum de métodos". o exemplo pode ser facilmente alterado paraforeach(IMyCompanyWidgetFrobber a in list) a.Frob(widget, context);
Jimmy

133

Gosto muito da resposta de Jimmy, mas sinto que preciso acrescentar algo a ela. A chave para tudo isso é o "capaz" no IProcess capaz. Indica uma capacidade (ou propriedade, mas significa "qualidade intrínseca", não no sentido de propriedades C #) do objeto que implementa a interface. O IAnimal provavelmente não é um bom exemplo para uma interface, mas o IWalkable pode ser uma boa interface se o seu sistema tiver muitas coisas que podem ser executadas. Você pode ter aulas derivadas de Animal, como Cão, Vaca, Peixe, Cobra. Os dois primeiros provavelmente implementariam o IWalkable, os dois últimos não andam, portanto não. Agora você pergunta "por que não apenas ter outra superclasse, WalkingAnimal, da qual derivam cão e vaca?". A resposta é quando você tem algo completamente fora da árvore de herança que também pode andar, como um robô. O robô implementaria o IWalkable, mas provavelmente não derivaria do Animal. Se você quiser uma lista de coisas que podem andar,

Agora substitua o IWalkable por algo mais semelhante ao software IPersistable, e a analogia fica muito mais próxima do que você veria em um programa real.


9
Eu gosto do que você criou - "Indica uma capacidade". As interfaces são realmente necessárias quando você precisa definir a capacidade, pois o básico precisa seguir sua classe "Base".
Ramiz Uddin 31/03

71

Use interfaces quando implementações da mesma funcionalidade diferirem.

Use classes abstratas / base quando precisar compartilhar uma implementação concreta comum.


8
O primeiro é chamado polimorfismo. O segundo é o óleo de cobra - a menos que sublcass seja classe base (não há violação do princípio de substituição de Liskov), você deve favorecer a composição sobre a herança.
Arnis Lapsa

@ArnisLapsa Não entendo bem o que você quer dizer com "a menos que sublcass seja classe básica". Quando uma subclasse não seria "classe básica"? (como na ispalavra - chave)
Marc.2377 22/02/19

32

Pense em uma interface como um contrato. É uma maneira de dizer: "Essas classes devem seguir esse conjunto de regras".

Portanto, no exemplo IAnimal, é uma maneira de dizer: "DEVO poder chamar Executar, Caminhar etc. nas classes que implementam IAnimal".

Por que isso é útil? Você pode criar uma função que se baseie no fato de que deve poder chamar Executar e Andar, por exemplo, no objeto. Você pode ter o seguinte:

public void RunThenWalk(Monkey m) {
    m.Run();
    m.Walk();
}

public void RunThenWalk(Dog d) {
    d.Run();
    d.Walk();
}

... e repita isso para todos os objetos que você sabe que podem correr e andar. No entanto, com sua interface IAnimal, você pode definir a função uma vez da seguinte maneira:

public void RunThenWalk(IAnimal a) {
    a.Run();
    a.Walk();
}

Ao programar na interface, você confia essencialmente nas classes para implementar a intenção da interface. Portanto, em nosso exemplo, o pensamento é: "Eu não ligo para como eles correm e andam, desde que corram e andem. Meu RunThenWalk será válido desde que cumpram esse contrato. Funciona perfeitamente bem sem saber mais nada sobre a classe."

Há também uma boa discussão nesta questão relacionada .


1
Não se esqueça da independência de implementação. Uma interface permite que você não se importe com a implementação da função subjacente, apenas que faz o que a interface diz que faz.
Matthew Brubaker

18

Não se preocupe tanto. Muitos desenvolvedores raramente precisarão escrever uma interface. Você freqüentemente usará interfaces disponíveis na estrutura .NET , mas se não sentir necessidade de escrever uma tão cedo, não há nada de surpreendente nisso.

O exemplo que eu sempre dou a alguém é se você tem uma aula de Veleiro e uma aula de Viper. Eles herdam a classe Boat e a classe Car, respectivamente. Agora diga que você precisa percorrer todos esses objetos e chamar o Drive()método deles . Enquanto você pode escrever um código como o seguinte:

if(myObject is Boat)
    ((Boat)myObject).Drive()
else
    if (myObject is Car)
        ((Car)myObject).Drive()

Seria muito mais simples escrever:

((IDrivable)myObject).Drive()

16

Jimmy está certo quando você deseja usar uma única variável para vários tipos, mas todos eles implementam o mesmo método por meio de uma declaração de interface. Então você pode chamá-los de método principal na variável digitada na interface.

Há uma segunda razão para usar interfaces, no entanto. Quando o arquiteto do projeto é uma pessoa diferente do codificador de implementação, ou existem vários codificadores de implementação e um gerente de projeto. O responsável pode escrever um monte de interfaces e verificar se o sistema interopera e deixar que os desenvolvedores preencham as interfaces com as classes de implementação. Essa é a melhor maneira de garantir que várias pessoas escrevam classes compatíveis e possam fazê-lo em paralelo.


15

Eu gosto da analogia do exército.

O sargento não se importa se você é desenvolvedor de software , músico ou advogado .
Você é tratado como soldado .

uml

É mais fácil para o sargento não se incomodar com detalhes específicos de pessoas com quem ele está trabalhando,
tratar todos como abstrações de soldados (... e puni-los quando eles falham em agir como aqueles).

A capacidade de as pessoas agirem como soldados é chamada polimorfismo.

Interfaces são construções de software que ajudam a alcançar o polimorfismo.

A necessidade de abstrair os detalhes para obter simplicidade é a resposta à sua pergunta.

Polimorfismo , que etimologicamente significa "muitas formas", é a capacidade de tratar um objeto de qualquer subclasse de uma classe base como se fosse um objeto da classe base. Uma classe base possui, portanto, muitas formas: a própria classe base e qualquer uma de suas subclasses.

(..) Isso torna seu código mais fácil para você escrever e mais fácil para outras pessoas entenderem. Isso também torna seu código extensível, porque outras subclasses podem ser adicionadas posteriormente à família de tipos, e os objetos dessas novas subclasses também funcionam com o código existente.


14

Na minha experiência, a força motriz para criar interfaces não ocorreu até eu começar a fazer testes de unidade com uma estrutura de simulação. Ficou bastante claro que o uso de interfaces tornaria a zombaria muito mais fácil (já que a estrutura dependia dos métodos serem virtuais). Quando comecei, vi o valor de abstrair a interface da minha classe da implementação. Mesmo se eu não criar uma interface real, tento agora tornar meus métodos virtuais (fornecendo uma interface implícita que pode ser substituída).

Existem muitas outras razões que eu descobri para reforçar a boa prática de refatoração para interfaces, mas o teste de unidade / zombaria foi o que proporcionou o "momento aha" inicial da experiência prática.

EDIT : Para esclarecer, com testes de unidade e zombaria, sempre tenho duas implementações - a implementação real e concreta e uma implementação de simulação alternativa usada nos testes. Depois de ter duas implementações, o valor da interface se torna óbvio - lide com ela em termos da interface para que você possa substituir a implementação a qualquer momento. Neste caso, estou substituindo-o por uma interface simulada. Eu sei que posso fazer isso sem uma interface real se minha classe for construída corretamente, mas o uso de uma interface real reforça isso e a torna mais limpa (mais clara para o leitor). Sem esse ímpeto, acho que não teria apreciado o valor das interfaces, já que a maioria das minhas classes apenas possui uma implementação concreta.


Coisa certa por razões erradas. No seu caso - você acaba com as chamadas "interfaces de cabeçalho" e adiciona um excesso de complexidade à simplicidade.
Arnis Lapsa

@Arnis - o teste de unidade é um "motivo errado", zombar facilmente das classes para remover dependências nos testes é um "motivo errado". Desculpe, mas eu discordo.
precisa saber é o seguinte

1
os testes devem influenciar o design indiretamente , fornecendo feedback se o código for ou não testável. adicionar pontos de extensibilidade para melhorar a testabilidade é como trapacear. Eu acho que Mark Seeman resume melhor bit.ly/esi8Wp
Arnis Lapsa

1
@Arnis - então você usa zombaria em todos os seus testes de unidade? Caso contrário, como você remove a dependência de dependências. Você está usando DI? O teste de unidade me levou a usar zombaria e DI; zombar e DI provaram o valor da boa prática de usar interfaces para definir contratos de uma maneira que nenhum entendimento acadêmico jamais poderia. Devido à minha adoção do TDD, meu código é muito menos acoplado do que teria sido. Eu acho que é uma coisa boa.
precisa saber é o seguinte

apenas dizendo que a decomposição que não ocorre nas chamadas articulações naturais leva a baixa coesão e complexidade desnecessária.
Arnis Lapsa

10

Alguns exemplos de não programação que podem ajudá-lo a ver os usos apropriados das interfaces na programação.

Existe uma interface entre dispositivos elétricos e a rede elétrica - é o conjunto de convenções sobre o formato dos plugues e soquetes e as tensões / correntes entre eles. Se você deseja implementar um novo dispositivo elétrico, desde que o plugue siga as regras, ele poderá obter serviços da rede. Isso torna a extensibilidade muito fácil e remove ou reduz os custos de coordenação : você não precisa notificar o fornecedor de energia elétrica sobre como o seu novo dispositivo funciona e chegar a um acordo em separado sobre como conectar seu novo dispositivo à rede.

Os países possuem bitolas ferroviárias padrão. Isso permite uma divisão do trabalho entre empresas de engenharia que instalam trilhos e empresas de engenharia que constroem trens para rodar nesses trilhos, e possibilita que as empresas ferroviárias substituam e atualizem trens sem reprojetar o sistema inteiro.

O serviço que uma empresa apresenta a um cliente pode ser descrito como uma interface: uma interface bem definida enfatiza o serviço e oculta os meios . Quando você coloca uma carta em uma caixa de correio, espera que o sistema postal entregue a carta dentro de um determinado período, mas não tem expectativas sobre como a carta é entregue: você não precisa saber e o serviço postal tem a flexibilidade de escolha o meio de entrega que melhor atenda aos requisitos e às circunstâncias atuais. Uma exceção a isso é a capacidade dos clientes de escolher o correio aéreo - esse não é o tipo de interface que um programador de computador moderno teria projetado, pois revela muito da implementação.

Exemplos da natureza: não gosto muito de exemplos de como comer (), makesSound (), movimentos (), etc. Eles descrevem o comportamento, o que é correto, mas não descrevem interações e como são ativadas . Os exemplos óbvios de interfaces que permitem interações na natureza estão relacionados à reprodução; por exemplo, uma flor fornece uma certa interface para uma abelha, para que a polinização possa ocorrer.


5

É inteiramente possível passar a vida inteira como desenvolvedor .net e nunca escrever suas próprias interfaces. Afinal, nós sobrevivemos bem sem eles por décadas e nossos idiomas ainda estavam completos em Turing.

Não sei por que você precisa de interfaces, mas posso fornecer uma lista de onde as usamos em nosso projeto atual:

  1. Em nosso modelo de plug-in, carregamos plug-ins por interface e fornecemos essa interface para que os gravadores de plug-in estejam em conformidade.

  2. Em nosso sistema de mensagens entre máquinas, todas as classes de mensagens implementam uma interface específica e são "desembrulhadas" usando a interface.

  3. Nosso sistema de gerenciamento de configurações define uma interface usada para definir e recuperar as configurações.

  4. Temos uma interface que usamos para evitar um problema desagradável de referência circular. (Não faça isso se não for necessário.)

Eu acho que se existe uma regra, é usar interfaces quando você deseja agrupar várias classes dentro de um relacionamento é-um, mas você não deseja fornecer nenhuma implementação na classe base.


5

Um exemplo de código (combinação de Andrew com um extra meu em qual é o objetivo das interfaces ), que também mostra o porquê da interface, em vez de uma classe abstrata em linguagens sem suporte para herança múltipla (c # e Java):

interface ILogger
{
    void Log();
}
class FileLogger : ILogger
{
    public void Log() { }
}
class DataBaseLogger : ILogger
{
    public void Log() { }
}
public class MySpecialLogger : SpecialLoggerBase, ILogger
{
    public void Log() { }
}

Observe que o FileLogger e o DataBaseLogger não precisam da interface (pode ser uma classe base abstrata do Logger). Mas considere que você é obrigado a usar um criador de logs de terceiros que o força a usar uma classe base (digamos que exponha métodos protegidos que você precisa usar). Como o idioma não suporta herança múltipla, você não poderá usar a abordagem de classe base abstrata.

Resumindo: use uma interface sempre que possível para obter flexibilidade extra em seu código. Sua implementação está menos vinculada, portanto, acomoda melhor para a mudança.


4

Usei interfaces de vez em quando e aqui está o meu uso mais recente (os nomes foram generalizados):

Eu tenho vários controles personalizados em um WinForm que precisam salvar dados no meu objeto de negócios. Uma abordagem é chamar cada controle separadamente:

myBusinessObject.Save(controlA.Data);
myBusinessObject.Save(controlB.Data);
myBusinessObject.Save(controlC.Data);

O problema com esta implementação é que sempre que adiciono um controle, tenho que entrar no meu método "Salvar dados" e adicionar o novo controle.

Alterei meus controles para implementar uma interface ISaveable que possui o método SaveToBusinessObject (...), agora meu método "Save Data" apenas repete os controles e, se encontrar um que é ISaveable, chama SaveToBusinessObject. Portanto, agora, quando um novo controle é necessário, tudo o que alguém precisa fazer é implementar o ISaveable nesse objeto (e nunca tocar em outra classe).

foreach(Control c in Controls)
{
  ISaveable s = c as ISaveable;

  if( s != null )
      s.SaveToBusinessObject(myBusinessObject);
}

O benefício muitas vezes não realizado para as interfaces é que você localiza as modificações. Uma vez definido, você raramente alterará o fluxo geral de um aplicativo, mas frequentemente fará alterações no nível de detalhe. Quando você mantém os detalhes em objetos específicos, uma alteração no ProcessA não afetará uma alteração no ProcessB. (As classes base também oferecem esse benefício.)

EDIT: Outro benefício é a especificidade das ações. Como no meu exemplo, tudo o que quero fazer é salvar os dados; Não me importo com o tipo de controle ou se ele pode fazer outra coisa - só quero saber se posso salvar os dados no controle. Isso deixa meu código salvo bem claro - não há verificações para ver se é texto, numérico, booleano ou qualquer outra coisa, porque o controle personalizado lida com tudo isso.


4

Você deve definir uma interface assim que forçar um comportamento para sua classe.

O comportamento de um animal pode envolver caminhar, comer, correr etc. Portanto, você os define como interfaces.

Outro exemplo prático é a interface ActionListener (ou Runnable). Você os implementaria quando precisar acompanhar um evento específico. Portanto, você precisa fornecer a implementação para o actionPerformed(Event e)método em sua classe (ou subclasse). Da mesma forma, para a interface Runnable, você fornece a implementação do public void run()método.

Além disso, você pode ter essas interfaces implementadas por qualquer número de classes.

Outra instância em que as interfaces são usadas (em Java) é implementar a herança múltipla oferecida em C ++.


3
Por favor, Deus os faça parar de dizer coisas como herança múltipla em relação às interfaces. Você não herda uma interface em uma classe. Você o implementa .
Andrei Rînea

4

Suponha que você queira modelar aborrecimentos que podem acontecer quando você tenta dormir.

Modelar antes das interfaces

insira a descrição da imagem aqui

class Mosquito {
    void flyAroundYourHead(){}
}

class Neighbour{
    void startScreaming(){}
}

class LampJustOutsideYourWindow(){
    void shineJustThroughYourWindow() {}
}

Como você vê claramente muitas coisas podem ser irritantes quando você tenta dormir.

Uso de classes sem interfaces

Mas quando se trata de usar essas classes, temos um problema. Eles não têm nada em comum. Você precisa chamar cada método separadamente.

class TestAnnoyingThings{
    void testAnnoyingThinks(Mosquito mosquito, Neighbour neighbour, LampJustOutsideYourWindow lamp){
         if(mosquito != null){
             mosquito.flyAroundYourHead();
         }
         if(neighbour!= null){
             neighbour.startScreaming();
         }
         if(lamp!= null){
             lamp.shineJustThroughYourWindow();
         }
    }
}

Modelo com interfaces

Para superar esse problema, podemos introduzir uma iterfaceinsira a descrição da imagem aqui

interface Annoying{
   public void annoy();

}

E implementá-lo dentro de classes

class Mosquito implements Annoying {
    void flyAroundYourHead(){}

    void annoy(){
        flyAroundYourHead();
    }
}

class Neighbour implements Annoying{
    void startScreaming(){}

    void annoy(){
        startScreaming();
    }
}

class LampJustOutsideYourWindow implements Annoying{
    void shineJustThroughYourWindow() {}

    void annoy(){
        shineJustThroughYourWindow();
    }
}

Uso com interfaces

O que tornará o uso dessas classes muito mais fácil

class TestAnnoyingThings{
    void testAnnoyingThinks(Annoying annoying){
        annoying.annoy();
    }
}

Ok, mas não precisa Neighboure LampJustOutsideYourWindowtambém tem que implementar Annoying?
Stardust

Sim, obrigado por apontar isso. Eu fiz uma edição com esta mudança
Marcin Szymczak

2

O exemplo mais fácil de se dar é algo como Processadores de pagamento (Paypal, PDS etc.).

Digamos que você crie uma interface IPaymentProcessor que possua os métodos ProcessACH e ProcessCreditCard.

Agora você pode implementar uma implementação concreta do Paypal. Fazer esses métodos chamarem funções específicas do PayPal.

Se você decidir mais tarde precisar mudar para outro provedor, poderá. Basta criar outra implementação concreta para o novo provedor. Como tudo o que você está vinculado é a sua interface (contrato), é possível trocar qual deles seu aplicativo usa sem alterar o código que o consome.


2

Também permite realizar testes de unidade Mock (.Net). Se sua classe usa uma interface, você pode simular o objeto em seus testes de unidade e facilmente testar a lógica (sem atingir o banco de dados, o serviço da web, etc.).

http://www.nmock.org/


2

Se você procurar os assemblies do .NET Framework e detalhar as classes base para qualquer um dos objetos padrão, notará muitas interfaces (membros nomeados como ISomeName).

As interfaces são basicamente para implementar estruturas, grandes ou pequenas. Eu me senti da mesma maneira com relação às interfaces até querer escrever uma estrutura própria. Também descobri que entender interfaces me ajudou a aprender estruturas muito mais rapidamente. No momento em que você deseja escrever uma solução mais elegante para praticamente qualquer coisa, verá que uma interface faz muito sentido. É como um método de deixar uma classe vestir as roupas apropriadas para o trabalho. Mais importante, as interfaces permitem que os sistemas se tornem muito mais auto-documentados, porque objetos complexos se tornam menos complexos quando a classe implementa interfaces, o que ajuda a categorizar sua funcionalidade.

As classes implementam interfaces quando desejam poder participar de uma estrutura explícita ou implicitamente. Por exemplo, IDisposable é uma interface comum que fornece assinatura de método para o método Dispose () popular e útil. Em uma estrutura, tudo o que você ou outro desenvolvedor precisa saber sobre uma classe é que, se ela implementar IDisposable, você saberá que ((IDisposable) myObject) .Dispose () estará disponível para ser chamado para fins de limpeza.

EXEMPLO CLÁSSICO: sem implementar a interface IDisposable, você não pode usar a construção de palavra-chave "using ()" em C #, porque exige que qualquer objeto especificado como parâmetro possa ser implicitamente convertido em IDisposable.

EXEMPLO COMPLEXO: Um exemplo mais complexo seria a classe System.ComponentModel.Component. Esta classe implementa IDisposable e IComponent. A maioria dos objetos .NET, se não todos, que possuem um designer visual associado a eles, implementa o IComponent para que o IDE possa interagir com o componente.

CONCLUSÃO: À medida que você se familiariza com o .NET Framework, a primeira coisa que você fará quando encontrar uma nova classe no Pesquisador de objetos ou na ferramenta .NET Reflector (gratuita) ( http://www.red-gate.com / products / reflector / ) é para verificar de qual classe ele herda e também as interfaces que ele implementa. O .NET Reflector é ainda melhor que o Pesquisador de objetos, pois também permite ver as classes derivadas. Isso permite que você aprenda sobre todos os objetos que derivam de uma classe específica, potencialmente aprendendo sobre a funcionalidade da estrutura que você não sabia que existia. Isso é particularmente significativo quando os namespaces atualizados ou novos são adicionados ao .NET Framework.


2

Considere que você está fazendo um jogo de tiro em primeira pessoa. O jogador tem várias armas para escolher.

Podemos ter uma interface Gunque define uma função shoot().

Precisamos de diferentes subclasses de Gunclasse, a saber, ShotGun Snipere assim por diante.

ShotGun implements Gun{
    public void shoot(){
       \\shotgun implementation of shoot.
    } 
}

Sniper implements Gun{
    public void shoot(){
       \\sniper implementation of shoot.
    } 
}

Classe de atirador

O atirador tem todas as armas em sua armadura. Vamos criar um Listpara representá-lo.

List<Gun> listOfGuns = new ArrayList<Gun>();

O atirador percorre suas armas, como e quando necessário, usando a função switchGun()

public void switchGun(){
    //code to cycle through the guns from the list of guns.
    currentGun = //the next gun in the list.
}

Podemos definir a arma atual, usando a função acima e simplesmente chamar a shoot()função, quando fire()for chamada.

public void fire(){
    currentGun.shoot();
}

O comportamento da função de disparo varia de acordo com diferentes implementações da Guninterface.

Conclusão

Crie uma interface, quando uma função de classe depende de uma função de outra classe , que está sujeita a alterar seu comportamento, com base na instância (objeto) da classe implementada.

por exemplo, a fire()função da Shooterclasse espera que as armas ( Sniper, ShotGun) implementem a shoot()função. Então, se trocarmos a arma e disparar.

shooter.switchGun();
shooter.fire();

Nós mudamos o comportamento da fire()função.


1

Expandir o que Larsenal disse. Uma interface é um contrato que todas as classes de implementação devem seguir. Por esse motivo, você pode usar uma técnica chamada programação para o contrato. Isso permite que seu software se torne independente da implementação.


1

As interfaces geralmente são usadas quando você deseja definir um comportamento que os objetos possam exibir.

Um bom exemplo disso no mundo .NET é a interface IDisposable , usada em todas as classes da Microsoft que usam recursos do sistema que devem ser liberados manualmente. Requer que a classe que o implementa tenha um método Dispose ().

(O método Dispose () também é chamado pela construção de linguagem using para VB.NET e C # , que funciona apenas em IDisposables)

Lembre-se de que você pode verificar se um objeto implementa uma interface específica usando construções como TypeOf ... Is(VB.NET), is(C #), instanceof(Java), etc.


1

Como várias pessoas provavelmente já responderam, as interfaces podem ser usadas para impor certos comportamentos entre classes que não os implementarão da mesma maneira. Portanto, ao implementar uma interface, você está dizendo que sua classe tem o comportamento da interface. A interface IAnimal não seria uma interface típica porque as classes Dog, Cat, Bird etc. são tipos de animais e provavelmente devem estendê-la, que é um caso de herança. Em vez disso, nesse caso, uma interface seria mais parecida com o comportamento animal, como IRunnable, IFlyable, ITrainable etc.

As interfaces são boas para muitas coisas, uma das principais coisas é a conectabilidade. Por exemplo, declarar um método que possui um parâmetro List permitirá que qualquer coisa que implemente a interface List seja transmitida, permitindo que o desenvolvedor remova e conecte uma lista diferente posteriormente, sem precisar reescrever uma tonelada de código.

É possível que você nunca use interfaces, mas se estiver criando um projeto do zero, especialmente uma estrutura de algum tipo, provavelmente desejará se familiarizar com elas.

Eu recomendaria a leitura do capítulo sobre interfaces em Java Design, de Coad, Mayfield e Kern. Eles explicam um pouco melhor do que o texto introdutório médio. Se você não usa Java, basta ler o início do capítulo, que é basicamente conceitos.


1

Como qualquer técnica de programação que adiciona flexibilidade ao seu sistema, as interfaces também adicionam algum nível de complexidade. Eles geralmente são ótimos e você pode usá-lo em qualquer lugar (você pode criar uma interface para todas as suas classes) - mas, ao fazê-lo, você criaria um sistema mais complexo que seria mais difícil de manter.

Há uma troca aqui, como de costume: flexibilidade sobre manutenção. Qual deles é mais importante ? Não há respostas - isso depende do projeto. Mas lembre-se de que todos os softwares precisarão ser mantidos ...

Portanto, meu conselho: não use interfaces até que você realmente precise delas. (Com o Visual Studio, você pode extrair uma interface de uma classe existente em 2 segundos - portanto, não se apresse.)

Dito isto, quando você precisa criar uma interface?

Faço isso quando refatorando um método que de repente precisa processar duas ou mais classes semelhantes. Em seguida, crio uma interface, atribuo essa interface às duas (ou mais) classes semelhantes e altero o tipo de parâmetro do método (substitua o tipo de classe pelo tipo de interface).

E funciona: o)

Uma exceção: quando zombar de objetos, a interface é muito mais fácil de usar. Então, eu costumo criar interface apenas para isso.

PS: quando escrevo "interface", quero dizer: "interface de qualquer classe base", incluindo classes de interface pura. Observe que as classes abstratas geralmente são uma aposta melhor do que as interfaces puras, pois você pode adicionar lógica a elas.

Atenciosamente, Sylvain.


1

As interfaces ficarão evidentes quando você se tornar um desenvolvedor de bibliotecas (alguém que codifica para outros codificadores). A maioria de nós começa como desenvolvedores de aplicativos , onde usamos APIs e bibliotecas de programação existentes.

Na mesma linha que as interfaces são um contrato , ninguém mencionou ainda que as interfaces são uma ótima maneira de tornar algumas partes do seu código estáveis . Isso é especialmente útil quando se trata de um projeto de equipe (ou quando você está desenvolvendo código usado por outros desenvolvedores). Então, aqui está um cenário concreto para você:

Quando você está desenvolvendo código em uma equipe , outras pessoas podem estar usando o código que você escreve. Eles ficarão mais felizes quando codificarem para suas interfaces (estáveis) e você ficará feliz quando tiver a liberdade de alterar suas implementações (ocultas atrás da interface) sem quebrar o código da sua equipe. É uma variante da ocultação de informações (as interfaces são públicas, as implementações estão ocultas dos programadores clientes). Leia mais sobre variações protegidas .

Consulte também esta pergunta relacionada sobre a codificação para uma interface .


1

Existem muitos propósitos para usar uma interface.

  1. Use no comportamento polimórfico. Onde você deseja chamar métodos específicos de uma classe filho com uma interface tendo uma referência à classe filho.

  2. Ter um contrato com as classes para implementar todos os métodos onde for necessário, como o uso mais comum, é com objetos COM, onde uma classe de wrapper é gerada em uma DLL que herda a interface; esses métodos são chamados nos bastidores e você só precisa implementá-los, mas com a mesma estrutura definida na DLL COM, que você só pode conhecer através da interface que eles expõem.

  3. Reduzir o uso de memória carregando métodos específicos em uma classe. Como se você tivesse três objetos de negócios e eles fossem implementados em uma única classe, você pode usar três interfaces.

Por exemplo, IUser, IOrder, IOrderItem

public interface IUser()
{

void AddUser(string name ,string fname);

}

// Same for IOrder and IOrderItem
//


public class  BusinessLayer: IUser, IOrder, IOrderItem

{    
    public void AddUser(string name ,string fname)
    {
        // Do stuffs here.
    }

    // All methods from all interfaces must be implemented.

}

Se você deseja adicionar apenas um usuário, faça o seguinte:

IUser user = new (IUser)BusinessLayer();

// It will load  all methods into memory which are declared in the IUser interface.

user.AddUser();
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.