Existe alguma diferença entre interfaces e classes abstratas que possuem apenas métodos abstratos?

9

Digamos que temos uma classe abstrata e deixemos que essa classe tenha apenas métodos abstratos. Essa classe abstrata é diferente de uma interface que possui apenas os mesmos métodos?

O que estou procurando saber é se existem diferenças filosoficamente, objetivamente e na implementação da linguagem de programação subjacente entre uma Classe Abstrata com apenas membros abstratos e uma Interface equivalente?

yfklon
fonte
qual língua?
Kevin Cline
até onde sei, sua pergunta é respondida em duplicado duas vezes : aqui e aqui . E essas duas respostas são agnósticos linguagem, específica nada para C # lá
mosquito
3
@blank Eu discordei do status Duplicar aplicado à sua pergunta, então a reabri. Além disso, editei sua pergunta para esclarecer melhor o que acredito que você está perguntando.
Maple_shaft

Respostas:

22

Tecnicamente, as diferenças não são realmente significativas, mas, conceitualmente, são coisas totalmente diferentes e isso leva às diferenças técnicas que outros mencionaram.

Uma superclasse abstrata é exatamente o que parece, é um tipo comum que é compartilhado por muitos outros tipos, como Gatos e Cães são Animais.

Uma interface também é exatamente o que parece, é uma interface através da qual outras classes podem se comunicar com o objeto. Se você deseja fazer uma Cat Walk, está bem, porque a Cat implementa uma interface CanWalk. O mesmo para um lagarto, embora eles andem de maneira muito diferente. Um Snake, por outro lado, não implementa o CanWalk, portanto você não pode dizer para Andar. Enquanto isso, Lizard e Snake (ou subclasses possivelmente mais explícitas - eu não sou especialista) podem perder a pele e, assim, implementar o CanShed, enquanto um gato não pode fazer isso.

Mas eles ainda são animais e têm propriedades comuns, como vivos ou mortos.

É por isso que todos os métodos em uma interface devem ser implementados como públicos (ou explicitamente, em C #). Porque qual é o ponto em uma interface que está oculta da classe que faz interface com o objeto? É também por isso que você pode ter várias interfaces para um objeto, mesmo quando um idioma não suporta herança múltipla.

Voltando à sua pergunta, quando você a vê dessa maneira, raramente há uma razão para ter uma superclasse inteiramente abstrata.

pdr
fonte
4
+1, embora os gatos verterem de uma maneira muito mais irritante do que cobras ou lagartos.
perfil completo de Matthew Flynn
Tecnicamente: Métodos abstratos podem ser protegidos. Métodos de interface não podem.
Jacques Koorts 15/03/19
19

Na maioria das linguagens OOP, uma classe de implementação pode derivar apenas de uma classe abstrata, mas implementar várias interfaces.

herzmeister
fonte
3
a maioria? quais você está contando? A maioria das linguagens OOP que conheço não possui interfaces ou classes abstratas. C ++ possui apenas classes abstratas.
Kevin Cline
10
@kevincline: provavelmente C #, Java e VB.NET.
tdammers
11
@ Kevincline, acho que falta apenas "ter os dois". IIRC, em Ada, a motivação para a interface era aquela: os designers não queriam um recurso geral de herança múltipla, mas o caso especial da interface era considerado importante demais para não ser fornecido.
AProgrammer 19/04
@ Tdammers: LOL. Isso foi uma piada, certo?
Kevin cline #
3

Em uma linguagem como C ++ que permite herança múltipla e não possui interfaces, as classes abstratas nas quais todos os métodos são abstratos podem servir como interfaces. Não trabalhei muito com C ++, mas acho que a herança múltipla pode causar problemas quando existem métodos com o mesmo nome nas classes base.

Em linguagens como PHP e C #, as interfaces fornecem um meio de obter polimorfismos semelhantes, embora eu não goste de chamá-lo de "herança", pois há uma diferença conceitual entre herdar uma classe abstrata e implementar uma interface. As interfaces removem o problema do conflito, porque elas próprias não fornecem implementação.

Uma interface serve como um contrato para o mundo exterior, enquanto uma classe abstrata pode fornecer uma implementação, embora, se usada para "falsificar" uma interface, provavelmente não funcionará.

A principal diferença conceitual é que quando uma classe herda outra classe (abstrata ou não), existe uma relação de "é", então a Caré um Vehiclee Dogé um Animal. Com uma interface, é o que o objeto faz que importa. Assim, ambos Care Dogpode Move()eo consumidor sabe disso porque implementar Movable, mas um carro não é definitivamente um Dog, ou um Animal. E a implementação da mudança será diferente (rodas x pernas), mas o código de consumo não se importa e não deve se importar. As interfaces são todas sobre o código de consumo, e não a implementação.

O ponto principal é que, se você tiver interfaces no idioma de sua escolha, use-as para coisas pelas quais elas estão lá. Caso contrário (como em C ++), você pode falsificá-las usando classes abstratas puras.

Ivan Pintar
fonte
A interface também é um tipo, então você pode ter um IAnimal que sãoDog e Cat são .
Amy Blankenship
Você poderia, mas na minha opinião, as interfaces são sobre comportamentos expostos ao mundo exterior, e não tanto sobre o que os objetos são. A herança implica que algo é um tipo de outra coisa (Gato é um Animal). Uma interface apenas diz o que esse objeto pode fazer. É por isso que eu gosto de dizer que algo "implementa" em vez de "herdar" de uma interface, que é o que a maioria das pessoas .Net com quem eu trabalhei diria (acho que porque a sintaxe é a mesma para herança e implementação).
precisa
2

As classes abstratas podem apresentar métodos abstratos protegidos (nos idiomas com os quais estou trabalhando), nas interfaces os métodos geralmente são sempre públicos. Se essa diferença permite explorações úteis, não sei.

Editar Primeiro pensei que um método abstrato privado não seria útil, mas agora lembrei que ele pode ser usado para garantir que esse método nunca seja chamado. Dessa forma, você pode impedir que um construtor de cópias de um objeto seja chamado.

Thomas
fonte
11
Métodos virtuais protegidos (substituíveis) podem ser úteis para classes que fazem parte de uma estrutura ou algo parecido. Dessa forma, eles garantem que o código personalizado em uma classe que herda o resumo forneça essa funcionalidade. Embora isso também pode ser alcançado por herdar uma interface na classe base, mas não realmente implementar os seus métodos
Ivan Pintar
Sim, eu estava pensando em algo assim, mas não tenho nenhuma experiência com isso, então não pude julgar. Obrigado pela contribuição.
Thomas
Apenas uma nota. Em alguns idiomas, métodos virtuais privados podem ser substituídos em classes derivadas.
Johan Boulé
2

Sim, eles são diferentes. Caso contrário, os designers de idiomas não teriam fornecido os dois. Conheço duas linguagens que separam classes e interfaces: Java e C #, clone mutante de Java. Os designers criaram interfaces para evitar o suporte à herança de várias classes. A maioria dos outros idiomas suporta herança de várias classes e, consequentemente, não separa classes e interfaces.

Kevin Cline
fonte
2

Eu acho que a principal diferença é que: em uma classe abstrata - mesmo que todos os métodos sejam abstratos, eles ainda podem fornecer membros de dados (variáveis ​​de instância) e algum código para as classes que o implementam (na forma de métodos ou construtores privados), blocos estáticos; fazendo parte do trabalho das subclasses e ajudando-as na implementação.

Um efeito colateral positivo: o código está em um lugar, portanto, em um lugar para fazer as correções. as subclasses podem simplesmente chamar o método de superclasse e, em seguida, fazer outra coisa ou nada se as ações de superclasse forem suficientes para o caso delas. A superclasse deseja que cada subclasse tome essa decisão, de modo que marcou toda a sua implementação como abstrata (algumas também podem estar vazias)

Não é relevante para a pergunta: mas ter interfaces significa que uma classe pode implementar dois contratos diferentes. Essa é uma vantagem de uma interface sobre uma super classe abstrata

tgkprog
fonte
11
Os métodos abstratos não são definidos sem nenhuma implementação e deixam a implementação para as classes herdadas?
Ivan Pintar
sim o seu direito, então eu acho que é apenas as variáveis, construtores e métodos estáticos e privadas se você contar os
tgkprog
@Pinetree, na prática, na maioria das vezes, você desejará pelo menos um pouco de código "real" em suas Classes Abstratas (pelo menos no idioma que eu uso, que não possui uma construção especial para Classes Abstratas).
Amy Blankenship
@AmyBlankenship sim, na maioria das vezes as classes abstratas têm código "real" (é para isso que elas existem). Mas eu estava me referindo a métodos abstratos, dentro do contexto de uma classe puramente abstrata que serve como interface em uma linguagem como C ++, que não possui interfaces.
precisa