Foi-me feito uma pergunta, gostaria que a minha resposta fosse revista aqui.
P: Em qual cenário é mais apropriado estender uma classe abstrata em vez de implementar a (s) interface (s)?
R: Se estivermos usando o padrão de design do método de modelo.
Estou correcto ?
Lamento se não fui capaz de colocar a questão claramente.
Eu sei a diferença básica entre classe abstrata e interface.
1) usar classe abstrata quando o requisito é tal que precisamos implementar a mesma funcionalidade em cada subclasse para uma operação específica (implementar o método) e funcionalidade diferente para algumas outras operações (apenas assinaturas de método)
2) use a interface se precisar colocar a assinatura para ser a mesma (e a implementação diferente) para que possa cumprir com a implementação da interface
3) podemos estender no máximo uma classe abstrata, mas podemos implementar mais de uma interface
Reiterando a pergunta: Existem outros cenários, além dos mencionados acima, onde especificamente precisamos usar a classe abstrata (veja se o modelo de design do método de modelo é conceitualmente baseado apenas nisso)?
Interface vs. classe abstrata
A escolha entre os dois realmente depende do que você deseja fazer, mas, felizmente para nós, Erich Gamma pode nos ajudar um pouco.
Como sempre, há uma compensação, uma interface oferece liberdade em relação à classe base, uma classe abstrata oferece a liberdade de adicionar novos métodos posteriormente . - Erich Gamma
Você não pode ir e mudar uma interface sem ter que mudar muitas outras coisas em seu código, então a única maneira de evitar isso seria criar uma interface totalmente nova, o que nem sempre é uma coisa boa.
Abstract classes
deve ser usado principalmente para objetos intimamente relacionados. Interfaces
são melhores em fornecer funcionalidade comum para classes não relacionadas.
fonte
Respostas:
Quando usar interfaces
Uma interface permite que alguém comece do zero para implementar sua interface ou implementar sua interface em algum outro código cujo propósito original ou principal seja bem diferente de sua interface. Para eles, sua interface é apenas incidental, algo que deve ser adicionado ao código deles para poder usar seu pacote. A desvantagem é que todos os métodos da interface devem ser públicos. Você pode não querer expor tudo.
Quando usar classes abstratas
Uma classe abstrata, em contraste, fornece mais estrutura. Geralmente define algumas implementações padrão e fornece algumas ferramentas úteis para uma implementação completa. O problema é que o código que o usa deve usar sua classe como base. Isso pode ser altamente inconveniente se os outros programadores que desejam usar seu pacote já desenvolveram sua própria hierarquia de classes independentemente. Em Java, uma classe pode herdar de apenas uma classe base.
Quando usar ambos
Você pode oferecer o melhor dos dois mundos, uma interface e uma classe abstrata. Os implementadores podem ignorar sua classe abstrata, se quiserem. A única desvantagem de fazer isso é chamar métodos por meio de seu nome de interface é um pouco mais lento do que chamá-los por meio de seu nome de classe abstrato.
fonte
If we are using template method design pattern
Não podemos dizerYES
ouNO
Sim, se você usar JAXB. Não gosta de interfaces. Você deve usar classes abstratas ou contornar essa limitação com genéricos.
De uma postagem de blog pessoal :
Interface:
Em geral, as interfaces devem ser usadas para definir contratos (o que deve ser alcançado, não como fazê-lo).
Classe abstrata:
Classes abstratas devem ser usadas para implementação (parcial). Eles podem ser um meio de restringir a maneira como os contratos de API devem ser implementados.
fonte
default
estatic
.A interface é usada quando você tem o cenário em que todas as classes têm a mesma estrutura, mas têm funcionalidades totalmente diferentes.
A classe abstrata é usada quando você tem o cenário em que todas as classes têm a mesma estrutura, mas algumas funcionalidades iguais e diferentes.
Dê uma olhada no artigo: http://shoaibmk.blogspot.com/2011/09/abstract-class-is-class-which-cannot-be.html
fonte
Há muitas respostas boas aqui, mas geralmente acho que usar AMBAS as interfaces e classes abstratas é o melhor caminho. Considere este exemplo inventado:
Você é um desenvolvedor de software em um banco de investimento e precisa construir um sistema que coloque pedidos em um mercado. Sua interface captura a ideia mais geral do que um sistema de negociação faz ,
1) Trading system places orders 2) Trading system receives acknowledgements
e pode ser capturado em uma interface,
ITradeSystem
public interface ITradeSystem{ public void placeOrder(IOrder order); public void ackOrder(IOrder order); }
Agora, os engenheiros que trabalham no balcão de vendas e em outras linhas de negócios podem começar a interagir com seu sistema para adicionar a funcionalidade de colocação de pedidos aos aplicativos existentes. E você ainda nem começou a construir! Este é o poder das interfaces.
Então você vai em frente e constrói o sistema para os corretores de ações ; eles ouviram dizer que seu sistema possui um recurso para localizar ações baratas e estão ansiosos para experimentá-lo! Você captura esse comportamento em um método chamado
findGoodDeals()
, mas também percebe que há um monte de coisas complicadas envolvidas na conexão com os mercados. Por exemplo, você deve abrir umSocketChannel
,public class StockTradeSystem implements ITradeSystem{ @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> } public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
As implementações concretas vão ter muitos desses métodos confusos, como
connectToMarket()
, masfindGoodDeals()
é tudo com que os comerciantes realmente se preocupam.Agora é aqui que as classes abstratas entram em jogo. Seu chefe informa que os negociantes de moeda também desejam usar seu sistema. E olhando para os mercados de câmbio, você vê que o encanamento é quase idêntico ao dos mercados de ações. Na verdade,
connectToMarket()
podem ser reutilizados literalmente para se conectar aos mercados de câmbio. No entanto,findGoodDeals()
é um conceito muito diferente na arena monetária. Portanto, antes de passar a base de código para o garoto mago do câmbio do outro lado do oceano, você primeiro refatora em umaabstract
classe, deixando nãofindGoodDeals()
implementadopublic abstract class ABCTradeSystem implements ITradeSystem{ public abstract void findGoodDeals(); @Override public void placeOrder(IOrder order); getMarket().place(order); @Override public void ackOrder(IOrder order); System.out.println("Order received" + order); private void connectToMarket(); SocketChannel sock = Socket.open(); sock.bind(marketAddress); <LOTS MORE MESSY CODE> }
Seu sistema de negociação de ações implementa
findGoodDeals()
como você já definiu,public class StockTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); deals = <apply magic wizardry> System.out.println("The best stocks to buy are: " + deals); }
mas agora o garoto prodígio do FX pode construir seu sistema simplesmente fornecendo uma implementação de
findGoodDeals()
para moedas; ela não tem que reimplementar as conexões de soquete ou mesmo os métodos de interface!public class CurrencyTradeSystem extends ABCTradeSystem{ public void findGoodDeals(); ccys = <Genius stuff to find undervalued currencies> System.out.println("The best FX spot rates are: " + ccys); }
A programação para uma interface é poderosa, mas aplicativos semelhantes geralmente reimplementam métodos de maneiras quase idênticas. O uso de uma classe abstrata evita reimplmentações, enquanto preserva o poder da interface.
Nota: pode-se perguntar por que
findGreatDeals()
não faz parte da interface. Lembre-se de que a interface define os componentes mais gerais de um sistema de negociação. Outro engenheiro pode desenvolver um sistema de negociação COMPLETAMENTE DIFERENTE, onde eles não se importam em encontrar bons negócios. A interface garante que o balcão de vendas também possa interagir com o sistema deles, portanto, é preferível não confundir sua interface com conceitos de aplicativos como "ótimas ofertas".fonte
O que você deve usar, classes abstratas ou interfaces?
Considere o uso de classes abstratas se alguma dessas instruções se aplicar ao seu caso de uso:
Você deseja compartilhar código entre várias classes estreitamente relacionadas.
Você espera que as classes que estendem sua classe abstrata tenham muitos métodos ou campos comuns ou exijam modificadores de acesso diferentes de público (como protected e private).
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 pertencem.
Considere o uso de interfaces se alguma dessas instruções se aplicar ao seu caso de uso:
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.
Você deseja especificar o comportamento de um determinado tipo de dados, mas não se preocupa com quem implementa seu comportamento.
Você deseja tirar proveito da herança múltipla de tipo.
http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
fonte
As coisas mudaram muito nos últimos três anos com a adição de novos recursos para fazer a interface com o lançamento do Java 8.
Na página de documentação do oracle na interface:
Como você citou em sua pergunta, a classe abstrata é mais adequada para o padrão de método de modelo em que você deve criar o esqueleto. A interface não pode ser usada aqui.
Mais uma consideração para preferir a classe abstrata à interface:
Você não tem implementação na classe base e apenas as subclasses precisam definir sua própria implementação. Você precisa de uma classe abstrata em vez de uma interface, pois deseja compartilhar o estado com as subclasses.
A classe abstrata estabelece "é uma" relação entre classes relacionadas e a interface fornece "uma" capacidade entre classes não relacionadas .
Com relação à segunda parte de sua pergunta, que é válida para a maioria das linguagens de programação, incluindo java antes do lançamento de java-8
Se você preferir a classe abstrata para fazer a interface com as duas considerações acima, deve repensar agora, pois os métodos padrão adicionaram recursos poderosos às interfaces.
Para selecionar um deles entre interface e classe abstrata, a página de documentação do Oracle cita que:
Consulte essas questões relacionadas para obter mais detalhes:
Interface vs classe abstrata (OO geral)
Como devo ter explicado a diferença entre uma interface e uma classe abstrata?
Em resumo: o equilíbrio está se inclinando mais para as interfaces agora .
Alguns padrões de projeto usam classes abstratas (sobre interfaces) além do padrão de método Template.
Padrões de criação:
Abstract_factory_pattern
Padrões estruturais:
Decorator_pattern
Padrões comportamentais:
Mediator_pattern
fonte
Você não está correto. Existem muitos cenários. Simplesmente não é possível reduzi-lo a uma única regra de 8 palavras.
fonte
A resposta mais curta é estender a classe abstrata quando algumas das funcionalidades que você procura já estiverem implementadas nela.
Se você implementar a interface, terá que implementar todos os métodos. Mas, para a classe abstrata, o número de métodos que você precisa implementar pode ser menor.
No padrão de design de modelo , deve haver um comportamento definido. Este comportamento depende de outros métodos abstratos. Ao criar uma subclasse e definir esses métodos, você realmente define o comportamento principal. O comportamento subjacente não pode ser em uma interface, pois a interface não define nada, apenas declara. Portanto, um padrão de design de modelo sempre vem com uma classe abstrata. Se você quiser manter o fluxo do comportamento intacto, deve estender a classe abstrata, mas não sobrescrever o comportamento principal.
fonte
Pure virtual functions can also be used where the method declarations are being used to define an interface - similar to what the interface keyword in Java explicitly specifies. In such a use, derived classes will supply all implementations. In such a design pattern, the abstract class which serves as an interface will contain only pure virtual functions, but no data members or ordinary methods.
Part (1/2)no data members or ordinary methods
[em Classe abstrata].Na minha opinião, a diferença básica é que
an interface can't contain non abstract methods while an abstract class can
. Portanto, se as subclasses compartilham um comportamento comum, esse comportamento pode ser implementado na superclasse e, portanto, herdado nas subclassesTambém citei o seguinte do livro "software architecture design ppatterns in java"
"Na linguagem de programação Java, não há suporte para herança múltipla. Isso significa que uma classe pode herdar apenas de uma única classe. Portanto, a herança deve ser usada apenas quando for absolutamente necessário. Sempre que possível, os métodos que denotam o comportamento comum devem ser declarados em a forma de uma interface Java a ser implementada por diferentes classes de implementadores. Mas as interfaces sofrem com a limitação de não poderem fornecer implementações de métodos. Isso significa que cada implementador de uma interface deve implementar explicitamente todos os métodos declarados em uma interface, mesmo quando alguns deles os métodos representam a parte invariável da funcionalidade e têm exatamente a mesma implementação em todas as classes do implementador, o que leva a um código redundante.O exemplo a seguir demonstra como o padrão Abstract Parent Class pode ser usado em tais casos sem a necessidade de implementações de métodos redundantes. "
fonte
As classes abstratas são diferentes das interfaces em dois aspectos importantes
fonte
Esta é uma boa pergunta. Os dois não são semelhantes, mas podem ser usados pelo mesmo motivo, como uma reescrita. Ao criar é melhor usar a Interface. Quando se trata de aula, é bom para depuração.
fonte
Abstract classes should be extended when you want to some common behavior to get extended
. A superclasse Abstract terá o comportamento comum e definirá o método abstrato / comportamento específico que as subclasses devem implementar.Interfaces allows you to change the implementation anytime allowing the interface to be intact
.fonte
Este é o meu entendimento, espero que isso ajude
Classes abstratas:
Interfaces:
fonte
Uso de resumo e interface:
Um tem "É-um-relacionamento" e outro tem "Tem-um-relacionamento"
As propriedades padrão foram definidas em abstrato e propriedades extras podem ser expressas por meio da interface.
Exemplo: -> Nos seres humanos temos algumas propriedades padrão que são comer, dormir etc. mas se alguém tiver outras atividades curriculares como nadar, jogar etc., essas podem ser expressas pela Interface.
fonte