Quando usar uma interface em vez de uma classe abstrata e vice-versa?


427

Essa pode ser uma pergunta genérica de POO. Eu queria fazer uma comparação genérica entre uma interface e uma classe abstrata com base em seu uso.

Quando alguém iria querer usar uma interface e quando alguém iria querer usar uma classe abstrata ?



1
Além das respostas abaixo, há uma boa lista curta de onde você pode preferir interfaces e onde você não pode: Quando usar interfaces: msdn.microsoft.com/en-us/library/3b5b8ezk(v=vs.80) .aspx
Anthony

use abstract quando não tiver certeza do que a classe fará. use a interface se você estiver.
Uğur Gümüşhan

Estou interessado em ver quantos desenvolvedores, que não trabalham na Microsoft, definem e usam interfaces no desenvolvimento do dia a dia.
user1451111

Respostas:


432

Eu escrevi um artigo sobre isso:

Classes abstratas e interfaces

Resumindo:

Quando falamos sobre classes abstratas, estamos definindo características de um tipo de objeto; especificando o que é um objeto .

Quando falamos sobre uma interface e definimos os recursos que prometemos fornecer, estamos falando em estabelecer um contrato sobre o que o objeto pode fazer.


114
Este foi ery útil: Interfaces do not express something like "a Doberman is a type of dog and every dog can walk" but more like "this thing can walk". Obrigado
aexl

2
Parece que seu link está morto.
Kim Ahlstrøm Meyn Mathiassen

A explicação de Alex abaixo, re: a diferença entre apenas descrever funções implementadas e também descrever estado armazenado, parece ser uma resposta melhor para essa pergunta, porque as diferenças não são apenas filosóficas.
Duncan Malashock

1
Duncan Malashock, na verdade não. A resposta de Jorge é a melhor. A resposta de Alex se concentra na mecânica, enquanto a de Jorge é mais na semântica.
Nazar Merza

8
Eu gosto da declaração perante a sua resposta especificados:Use abstract classes and inheritance if you can make the statement “A is a B”. Use interfaces if you can make the statement “A is capable of [doing] as”
S1R-Lanzelot

433

Uma classe abstrata pode ter estado ou funcionalidade compartilhada. Uma interface é apenas uma promessa para fornecer o estado ou a funcionalidade. Uma boa classe abstrata reduzirá a quantidade de código que precisa ser reescrita porque sua funcionalidade ou estado pode ser compartilhado. A interface não possui informações definidas para serem compartilhadas


65
Esta, para mim, é a melhor resposta aqui e é uma pena que não tenha sido votada mais. Sim, existem diferenças filosóficas entre os dois conceitos, mas o ponto principal é que as classes abstratas garantem que todos os descendentes compartilhem funcionalidade / estado, onde uma interface garante apenas um vínculo comum.
drharris

3
Por exemplo, uma classe base abstrata é usada para o padrão de design do método de modelo, enquanto uma interface é usada para o padrão de design da estratégia .
precisa

1
Acho que o resumo de Jorge explica o principal por trás da existência para os dois, enquanto a resposta de Alex é a diferença nos resultados. Eu gostaria de poder marcar as duas como as respostas certas, mas ainda prefiro a resposta de Jorge.
Chirantan

E aqui está o exemplo com o código.
precisa

Para mim, essa "Uma boa classe abstrata reduzirá a quantidade de código que precisa ser reescrita porque sua funcionalidade ou estado pode ser compartilhado". declaração é o núcleo da resposta.
Div Tiwari

82

Pessoalmente, quase nunca tenho a necessidade de escrever aulas abstratas.

Na maioria das vezes eu vejo as classes abstratas sendo (mis) usadas, é porque o autor da classe abstrata está usando o padrão "Método de modelo".

O problema com o "método Template" é que ele quase sempre é reentrante - a classe "derivada" sabe não apenas sobre o método "abstrato" de sua classe base que está implementando, mas também sobre os métodos públicos da classe base , mesmo que na maioria das vezes não precise chamá-los.

Exemplo (simplificado demais):

abstract class QuickSorter
{
    public void Sort(object[] items)
    {
        // implementation code that somewhere along the way calls:
        bool less = compare(x,y);
        // ... more implementation code
    }
    abstract bool compare(object lhs, object rhs);
}

Então, aqui, o autor desta classe escreveu um algoritmo genérico e pretende que as pessoas o usem "especializando-o", fornecendo seus próprios "ganchos" - nesse caso, um método "comparar".

Portanto, o uso pretendido é algo como isto:

class NameSorter : QuickSorter
{
    public bool compare(object lhs, object rhs)
    {
        // etc.
    }
}

O problema é que você juntou indevidamente dois conceitos:

  1. Uma maneira de comparar dois itens (qual item deve ser o primeiro)
  2. Um método de classificação de itens (por exemplo, classificação quicksort vs merge etc.)

No código acima, teoricamente, o autor do método "compare" pode reincidir novamente no método "Sort" da superclasse ... mesmo que na prática eles nunca desejem ou precisem fazer isso.

O preço pago por esse acoplamento desnecessário é que é difícil alterar a superclasse e, na maioria dos idiomas OO, é impossível alterá-lo em tempo de execução.

O método alternativo é usar o padrão de design "Estratégia":

interface IComparator
{
    bool compare(object lhs, object rhs);
}

class QuickSorter
{
    private readonly IComparator comparator;
    public QuickSorter(IComparator comparator)
    {
        this.comparator = comparator;
    }

    public void Sort(object[] items)
    {
        // usual code but call comparator.Compare();
    }
}

class NameComparator : IComparator
{
    bool compare(object lhs, object rhs)
    {
        // same code as before;
    }
}

Portanto, observe agora: tudo o que temos são interfaces e implementações concretas dessas interfaces. Na prática, você realmente não precisa de mais nada para fazer um projeto OO de alto nível.

Para "ocultar" o fato de termos implementado "classificação de nomes" usando uma classe "QuickSort" e um "NameComparator", ainda podemos escrever um método de fábrica em algum lugar:

ISorter CreateNameSorter()
{
    return new QuickSorter(new NameComparator());
}

Sempre que houver uma classe abstrata, você poderá fazer isso ... mesmo quando houver um relacionamento reentrante natural entre a classe base e a classe derivada, geralmente vale a pena torná-las explícitas.

Um pensamento final: tudo o que fizemos acima é "compor" uma função "NameSorting" usando uma função "QuickSort" e uma função "NameComparison" ... em uma linguagem de programação funcional, esse estilo de programação se torna ainda mais natural, com menos código.


5
Só porque você pode usar classes Abstratas ou padrão de Método de Modelo não significa que você precisa evitá-las. O Padrão de Estratégia é um padrão diferente para uma situação diferente, como neste exemplo, mas há muitos exemplos em que um padrão de modelo é muito mais adequado que a Estratégia.
Jorge Córdoba

5
Bem, na minha experiência, nunca os encontro (situações em que o método de modelo é preferível) ... ou raramente de qualquer maneira. E isso é tudo o suporte de linguagem "abstrato" para o padrão de design do "método de modelo".
22909 Paul Hollingsworth

Ok, eu usei uma vez para um sistema especialista em que o processo era algo como: obtenha 1. FillTheParameters, 2. Crie o produto vetorial entre eles, 3. Para o resultado da computação para cada par, 4. Junte-se aos resultados, onde as etapas 1 e 3 onde delegados e 2 e 4 implementados na classe base.
Jorge Córdoba

10
Acho quase todo uso de classes abstratas mais difícil de entender. Pensar em termos de caixas que se comunicam entre si em vez de relacionamentos de herança é mais fácil (para mim) ... Mas eu também concordo que as linguagens OO atuais forçam muito clichê ... Funcional será o caminho a percorrer OO
Paul Hollingsworth

4
O exemplo de uso indevido é bastante trivial. Raramente se resume a essa funcionalidade despojada, como comparar. Muito mais comuns são situações em que há alguma funcionalidade padrão que as classes derivadas substituem ou estendem (e, no último caso, é perfeitamente válido chamar a função de classe base). No seu exemplo, não há funcionalidade padrão, portanto, o uso da classe abstrata não tem justificativa.
SomeWittyUsername

41

Se você está vendo java como linguagem OOP,

" interface não fornece implementação de método " não é mais válido com o lançamento do Java 8. Agora o java fornece implementação na interface para métodos padrão.

Em termos simples, eu gostaria de usar

interface: Para implementar um contrato por vários objetos não relacionados. Ele fornece a capacidade " TEM A ".

classe abstrata: Para implementar o mesmo ou diferente comportamento entre vários objetos relacionados. Estabelece uma relação" IS A ".

O site da Oracle fornece as principais diferenças entre interfacee abstractclasse.

Considere usar classes abstratas se:

  1. Você deseja compartilhar código entre várias classes estreitamente relacionadas.
  2. Você espera que as classes que estendem sua classe abstrata tenham muitos métodos ou campos comuns ou exijam modificadores de acesso que não sejam públicos (como protegido e privado).
  3. Você deseja declarar campos não estáticos ou não finais.

Considere usar interfaces se:

  1. Você espera que classes não relacionadas implementem sua interface. Por exemplo, muitos objetos não relacionados podem implementar a Serializableinterface.
  2. Você deseja especificar o comportamento de um tipo de dados específico, mas não se preocupa com quem implementa seu comportamento.
  3. Você deseja tirar proveito da herança múltipla do tipo.

Exemplo:

Classe abstrata ( IS A relação )

Leitor é uma classe abstrata.

BufferedReader é umReader

O FileReader é umReader

FileReadere BufferedReadersão usados ​​para fins comuns: leitura de dados e são relacionados por meio deReader classe.

Interface ( capacidade HAS A )

Serializable é uma interface.

Suponha que você tenha duas classes em seu aplicativo, que estão implementando a Serializableinterface

Employee implements Serializable

Game implements Serializable

Aqui você não pode estabelecer nenhuma relação por meio da Serializableinterface entre Employeee Game, que é para fins diferentes. Ambos são capazes de serializar o estado e a comparação termina aí.

Dê uma olhada nessas postagens:

Como devo ter explicado a diferença entre uma interface e uma classe abstrata?


40

OK, tendo acabado de "grunhir" isso sozinho - aqui está nos termos dos leigos (fique à vontade para me corrigir se eu estiver errado) - eu sei que esse tópico é demais, mas alguém pode tropeçar nele um dia ...

As classes abstratas permitem criar um blueprint, além de CONSTRUIR (implementar) propriedades e métodos que você deseja que TODOS os seus descendentes possuam.

Uma interface, por outro lado, permite apenas declarar que você deseja que propriedades e / ou métodos com um determinado nome existam em todas as classes que a implementam - mas não especifica como você deve implementá-la. Além disso, uma classe pode implementar MUITAS interfaces, mas só pode estender UMA classe Abstrata. Uma interface é mais uma ferramenta de arquitetura de alto nível (que fica mais clara se você começar a entender os padrões de design) - um resumo tem um pé nos dois campos e também pode realizar parte do trabalho sujo.

Por que usar um sobre o outro? O primeiro permite uma definição mais concreta de descendentes - o segundo permite um maior polimorfismo . Este último ponto é importante para o usuário final / codificador, que pode utilizar essas informações para implementar o AP I (interface) em uma variedade de combinações / formas para atender às suas necessidades.

Eu acho que esse foi o momento da "lâmpada" para mim - pense nas interfaces menos da perspectiva do autor e mais da de qualquer codificador vindo mais tarde na cadeia que esteja adicionando implementação a um projeto ou estendendo uma API.


para construir sobre isso: Um objeto que implementa uma interface assume seu tipo. Isto é crucial. Portanto, você pode passar diferentes variações da interface para uma classe, mas consulte-as (e seus métodos) COM O TIPO NOME DA INTERFACE. Assim, você elimina a necessidade de um switch ou loop if / else. Experimente este tutorial sobre o assunto - ele demonstra o uso de uma interface através do Padrão de Estratégia. phpfreaks.com/tutorial/design-patterns---strategy-and-bridge/…
sunwukung

Concordo plenamente com o seu momento da lâmpada: "API (interface) em uma variedade de combinações / formas para atender às suas necessidades"! Muito, muito bom ponto a fazer.
Trevor Boyd Smith

39

Meus dois centavos:

Uma interface basicamente define um contrato, ao qual qualquer classe de implementação deve aderir (implementar os membros da interface). Não contém nenhum código.

Por outro lado, uma classe abstrata pode conter código e pode haver alguns métodos marcados como abstratos que uma classe herdada deve implementar.

As raras situações em que usei classes abstratas são quando tenho algumas funcionalidades padrão nas quais a classe herdada pode não ser interessante em substituir, por exemplo, uma classe base abstrata, da qual algumas classes especializadas herdam.

Exemplo (muito rudimentar!): Considere uma classe base chamada Customer, que possui métodos abstratos como CalculatePayment(), CalculateRewardPoints()e alguns métodos não abstratos comoGetName() , SavePaymentDetails().

Classes especializadas gostam RegularCustomer e GoldCustomerherdarão da Customerclasse base e implementarão sua própria lógica CalculatePayment()e o CalculateRewardPoints()método, mas reutilizarão a classeGetName() e SavePaymentDetails()métodos.

Você pode adicionar mais funcionalidades a uma classe abstrata (métodos não abstratos) sem afetar as classes filho que estavam usando uma versão mais antiga. Enquanto a adição de métodos a uma interface afetaria todas as classes que a implementam, uma vez que precisariam agora implementar os membros da interface recém-adicionados.

Uma classe abstrata com todos os membros abstratos seria semelhante a uma interface.


1
+1 para "Você pode adicionar mais funcionalidade a uma classe abstrata (métodos não abstratos) sem afetar as classes filho que estavam usando uma versão mais antiga. Considerando que a adição de métodos a uma interface afetaria todas as classes que a implementam, pois agora elas precisariam implementar os membros da interface recém-adicionados ".
Div Tiwari

interfaces podem ter métodos "padrão", portanto, não ter nenhum método impl em interfaces é uma idéia errada. O relacionamento IS-A "pai-filho" é a chave aqui. Além disso, "Atributos compartilhados" vs. "Propriedades compartilhadas". por exemplo, Dog is-A Animal. Mas um cão também pode "Andar"
ha9u63ar 07/12/19

30

Quando fazer o que é uma coisa muito simples, se você tiver o conceito claro em sua mente.

Classes abstratas podem ser derivadas, enquanto as interfaces podem ser implementadas. Há alguma diferença entre os dois. Quando você deriva de uma classe Abstract, o relacionamento entre a classe derivada e a classe base é 'é um'. por exemplo, um cão é um animal, uma ovelha é um animal, o que significa que uma classe derivada está herdando algumas propriedades da classe base.

Enquanto na implementação de interfaces, o relacionamento é "pode ​​ser". por exemplo, um cão pode ser um cão espião. Um cachorro pode ser um cachorro de circo. Um cão pode ser um cão de corrida. O que significa que você implementa certos métodos para adquirir algo.

Espero estar claro.


11

1. Se você estiver criando algo que fornece funcionalidade comum para classes não relacionadas, use uma interface.

2. Se você estiver criando algo para objetos que estão intimamente relacionados em uma hierarquia, use uma classe abstrata.



7

Eu acho que a maneira mais sucinta de colocar isso é a seguinte:

Propriedades compartilhadas => classe abstrata.
Funcionalidade compartilhada => interface.

E para dizer de forma menos sucinta ...

Exemplo de classe abstrata:

public abstract class BaseAnimal
{
    public int NumberOfLegs { get; set; }

    protected BaseAnimal(int numberOfLegs)
    {
        NumberOfLegs = numberOfLegs;
    }
}

public class Dog : BaseAnimal
{
    public Dog() : base(4) { }
}

public class Human : BaseAnimal 
{
    public Human() : base(2) { }
}

Como os animais têm uma propriedade compartilhada - número de pernas neste caso - faz sentido criar uma classe abstrata contendo essa propriedade compartilhada. Isso também nos permite escrever código comum que opera nessa propriedade. Por exemplo:

public static int CountAllLegs(List<BaseAnimal> animals)
{
    int legCount = 0;
    foreach (BaseAnimal animal in animals)
    {
        legCount += animal.NumberOfLegs;
    }
    return legCount;
}

Exemplo de interface:

public interface IMakeSound
{
    void MakeSound();
}

public class Car : IMakeSound
{
    public void MakeSound() => Console.WriteLine("Vroom!");
}

public class Vuvuzela : IMakeSound
{
    public void MakeSound() => Console.WriteLine("VZZZZZZZZZZZZZ!");        
}

Observe aqui que Vuvuzelas e Carros são coisas completamente diferentes, mas eles têm uma funcionalidade compartilhada: fazer um som. Assim, uma interface faz sentido aqui. Além disso, permitirá que os programadores agrupem coisas que emitem sons sob uma interface comum - IMakeSoundneste caso. Com esse design, você pode escrever o seguinte código:

List<IMakeSound> soundMakers = new List<ImakeSound>();
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Car());
soundMakers.Add(new Vuvuzela());
soundMakers.Add(new Vuvuzela());

foreach (IMakeSound soundMaker in soundMakers)
{
    soundMaker.MakeSound();
}

Você pode dizer o que isso resultaria?

Por fim, você pode combinar os dois.

Exemplo combinado:

public interface IMakeSound
{
    void MakeSound();
}

public abstract class BaseAnimal : IMakeSound
{
    public int NumberOfLegs { get; set; }

    protected BaseAnimal(int numberOfLegs)
    {
        NumberOfLegs = numberOfLegs;
    }

    public abstract void MakeSound();
}

public class Cat : BaseAnimal
{
    public Cat() : base(4) { }

    public override void MakeSound() => Console.WriteLine("Meow!");
}

public class Human : BaseAnimal 
{
    public Human() : base(2) { }

    public override void MakeSound() => Console.WriteLine("Hello, world!");
}

Aqui, exigimos que todos BaseAnimalfaçam um som, mas ainda não sabemos sua implementação. Nesse caso, podemos abstrair a implementação da interface e delegar sua implementação às suas subclasses.

Um último ponto, lembre-se de que, no exemplo da classe abstrata, fomos capazes de operar nas propriedades compartilhadas de objetos diferentes e no exemplo da interface, fomos capazes de invocar a funcionalidade compartilhada de objetos diferentes? Neste último exemplo, poderíamos fazer as duas coisas.


7

Quando preferir uma classe abstrata à interface?

  1. Se alguém planeja atualizar uma classe base ao longo da vida de um programa / projeto, é melhor permitir que a classe base seja uma classe abstrata
  2. Se alguém está tentando criar uma espinha dorsal para objetos que estão intimamente relacionados em uma hierarquia, é altamente benéfico usar uma classe abstrata

Quando preferir uma interface à classe abstrata?

  1. Se não se lida com um tipo hierárquico maciço de estrutura, as interfaces seriam uma ótima opção
  2. Como a herança múltipla não é suportada com classes abstratas (problema de diamante), as interfaces podem salvar o dia

O que fez você pensar que uma pergunta de quase uma década precisava de uma 22ª resposta?
precisa saber é o seguinte

3
O mesmo tipo de pensamento que me fez procurar uma resposta simples para a pergunta.
Satya

1
FWIW, eu realmente amo essa resposta.
Brent Rittenhouse

6

As classes podem herdar de apenas uma classe base; portanto, se você deseja usar classes abstratas para fornecer polimorfismo a um grupo de classes, todas elas devem herdar dessa classe. As classes abstratas também podem fornecer membros que já foram implementados. Portanto, você pode garantir uma certa quantidade de funcionalidade idêntica a uma classe abstrata, mas não com uma interface.

Aqui estão algumas recomendações para ajudá-lo a decidir se deve usar uma interface ou uma classe abstrata para fornecer polimorfismo para seus componentes.

  • Se você antecipar a criação de várias versões do seu componente, crie uma classe abstrata. As classes abstratas fornecem uma maneira simples e fácil de fazer a versão de seus componentes. Ao atualizar a classe base, todas as classes herdadas são atualizadas automaticamente com a alteração. As interfaces, por outro lado, não podem ser alteradas depois de criadas dessa maneira. Se uma nova versão de uma interface for necessária, você deverá criar uma nova interface.
  • Se a funcionalidade que você está criando for útil em uma ampla variedade de objetos diferentes, use uma interface. As classes abstratas devem ser usadas principalmente para objetos que estão intimamente relacionados, enquanto as interfaces são mais adequadas para fornecer funcionalidade comum a classes não relacionadas.
  • Se você estiver projetando pequenos e concisos bits de funcionalidade, use interfaces. Se você estiver projetando grandes unidades funcionais, use uma classe abstrata.
  • Se você deseja fornecer funcionalidade implementada comum entre todas as implementações do seu componente, use uma classe abstrata. As classes abstratas permitem implementar parcialmente sua classe, enquanto as interfaces não contêm implementação para nenhum membro.

Copiado de:
http://msdn.microsoft.com/en-us/library/scsyfw1d%28v=vs.71%29.aspx


Não há nada na UML que impeça a herança de várias classes. A herança múltipla é determinada por uma linguagem de programação, não pela UML. Por exemplo, a herança de várias classes não é permitida em Java e C #, pois é permitida em C ++.
precisa saber é o seguinte

@BobRodes: Existem vários recursos que as estruturas orientadas a objetos podem fornecer em várias combinações, mas não em todas as combinações. A herança múltipla generalizada exclui algumas outras combinações úteis de recursos, incluindo a capacidade de converter uma referência diretamente para qualquer tipo pai da instância real ou qualquer tipo de interface suportado e a capacidade de compilar independentemente tipos de base e tipos derivados e uni-los em tempo de execução.
Supercat

@supercat O seu é uma boa explicação de alguns dos problemas resultantes do uso de herança múltipla. No entanto, não há nada na UML que impeça a herança de várias classes em um diagrama. Eu estava respondendo ao "Classes podem herdar de apenas uma classe base ..." o que não é bem assim.
BobRodes

@BobRodes: A pergunta foi marcada com Java. Java inclui os recursos indicados e, portanto, limita-se a formas de herança múltipla que não podem produzir um "diamante mortal" (embora, de fato, a maneira como eles implementaram implementações de interface padrão torne possível o diamante mortal).
supercat 21/07

@ supercat Oh, ok. Normalmente, não olho para tags java, então, na época em que escrevi, pensei que estava comentando uma resposta UML. De qualquer forma, concordo com o seu comentário.
22716 BobRodes

3

Considere usar classes abstratas se alguma destas instruções se aplicar à sua situação:

  1. Você deseja compartilhar código entre várias classes estreitamente relacionadas.
  2. Você espera que as classes que estendem sua classe abstrata tenham muitos métodos ou campos comuns ou exijam modificadores de acesso que não sejam públicos (como protegido e privado).
  3. Você deseja declarar campos não estáticos ou não finais. Isso permite definir métodos que podem acessar e modificar o estado do objeto ao qual eles pertencem.

Considere usar interfaces se alguma destas instruções se aplicar à sua situação:

  1. Você espera que classes não relacionadas implementem sua interface. Por exemplo, as interfaces Comparable e Cloneable são implementadas por muitas classes não relacionadas.
  2. Você deseja especificar o comportamento de um tipo de dados específico, mas não se preocupa com quem implementa seu comportamento.
  3. Você deseja tirar proveito de várias heranças.

Fonte


2

As respostas variam entre os idiomas. Por exemplo, em Java, uma classe pode implementar (herdar de) várias interfaces, mas herdar apenas de uma classe abstrata. Portanto, as interfaces oferecem mais flexibilidade. Mas isso não é verdade em C ++.


2

Para mim, eu usaria interfaces em muitos casos. Mas eu prefiro aulas abstratas em alguns casos.

As classes em OO geralmente se referem à implementação. Uso classes abstratas quando quero forçar alguns detalhes de implementação para os filhos, caso contrário eu vou com interfaces.

Obviamente, as classes abstratas são úteis não apenas para forçar a implementação, mas também para compartilhar alguns detalhes específicos entre muitas classes relacionadas.


1

Use uma classe abstrata se desejar fornecer algumas implementações básicas.


1
Obrigado Sebastian. Mas e se eu não precisar de uma implementação básica? Uma classe e interface abstratas não serão as mesmas, então, se essa é a única diferença entre elas? Por que existe uma diferença?
Chirantan

1
Porque algumas linguagens não possuem interfaces - C ++.
jmucchiello

1

em java, você pode herdar de uma classe (abstrata) para "fornecer" a funcionalidade e implementar várias interfaces para "garantir" a funcionalidade


dica: se você deseja herdar de uma classe abstrata e de uma interface, certifique-se de que a classe abstrata implemente a interface
Andreas Niedermair

1

Puramente com base na herança, você usaria um Resumo em que está definindo relacionamentos abstratos claramente descendentes (ou seja, animal-> gato) e / ou requer a herança de propriedades virtuais ou não públicas, especialmente o estado compartilhado (que a Interfaces não pode suportar )

Você deve tentar favorecer a composição (via injeção de dependência) sobre a herança, onde puder, e observe que as Interfaces sendo contratos suportam testes de unidade, separação de preocupações e (variação de idioma) herança múltipla de uma maneira que os Abstracts não podem.


1

Um local interessante em que as interfaces se saem melhor do que as classes abstratas é quando você precisa adicionar funcionalidade extra a um grupo de objetos (relacionados ou não). Se você não pode fornecer a eles uma classe abstrata base (por exemplo, eles são sealedou já têm um pai), você pode fornecer uma interface fictícia (vazia) e simplesmente escrever métodos de extensão para essa interface.


0

Pode ser uma decisão muito difícil de fazer ...

Um ponteiro que posso dar: Um objeto pode implementar muitas interfaces, enquanto um objeto pode herdar apenas uma classe base (em uma linguagem OO moderna como c #, eu sei que o C ++ tem herança múltipla - mas isso não é desaprovado?)


A herança múltipla permite que o Mixin seja implementado de maneira aparente; os Mixin bem escritos são muito fáceis de trabalhar, mas muito difíceis de encontrar e difíceis de escrever sem ficar aquém de algum lugar. Mixin's são muito legais como um todo, embora a IMO.
Martijn Laarman

Na verdade, não, herança múltipla é de fato um debate certo entre nós, geeks, que não vejo absolutamente nenhuma razão para desistir. Na verdade, votei na sua resposta.
Martijn Laarman

O único ponto que tentei destacar é que também é possível criar maneiras de misturar em linguagens com herança única (C #, PHP, javascript), mas através de comportamento hacky ou sintaxe brega. Eu amo o Mixin's quando eles trabalham, mas eu ainda sou indeciso quanto a herança múltipla ou não.
Martijn Laarman

Essa resposta é mais uma diferença sintática do que uma diferença de design. Eu acho que ele está pedindo uma diferença de design
Pramod Setlur

0

Uma classe abstrata pode ter implementações.

Uma interface não possui implementações, simplesmente define um tipo de contrato.

Também pode haver algumas diferenças dependentes do idioma: por exemplo, o C # não tem herança múltipla, mas várias interfaces podem ser implementadas em uma classe.


Quando você diz "um tipo de contrato", você quer dizer como em serviços da web?
Chirantan

Tecnicamente falando, os serviços da web não funcionam com interfaces. Com contrato, quero dizer que o usuário de um objeto sabe quais métodos estão presentes nesse objeto. Por exemplo, uma interface IMouse terá um método Move e um evento de botão esquerdo e direito do mouse.
Gerrie Schenck

-1

A regra básica do polegar é: Para "Substantivos", use a classe Abstract e para "Verbos", use a interface

Por exemplo: caré uma classe abstrata e drive, podemos torná-la uma interface.


5
Isso não faz sentido, também podemos colocar a funcionalidade driveno carro - que é uma classe abstrata.
Arslan Ali
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.