Diferença entre Classe Abstrata e Interface é uma das perguntas populares em entrevistas. Classe Abstrata e Interface são partes essenciais da linguagem de programação Java. Escolher entre uma interface ou uma classe abstrata é uma decisão de design enfrentada por todo arquiteto. Em meus artigos anteriores, forneci o máximo possível de detalhes sobre a interface Java e classe abstrata. Neste post, aprenderemos sobre a diferença entre classe abstrata e interface e quando devemos usar interface em vez da classe abstrata e vice-versa.
Diferença entre Classe Abstrata e Interface
- A palavra-chave
abstract
é usada para criar uma classe abstrata e pode ser usada com métodos, enquanto a palavra-chaveinterface
é usada para criar uma interface e não pode ser usada com métodos. - Subclasses utilizam a palavra-chave
extends
para estender uma classe abstrata e precisam fornecer a implementação de todos os métodos declarados na classe abstrata, a menos que a subclasse também seja uma classe abstrata. Por outro lado, subclasses utilizam a palavra-chaveimplements
para implementar interfaces e devem fornecer a implementação de todos os métodos declarados na interface. - Classes abstratas podem ter métodos com implementação, enquanto interfaces fornecem abstração absoluta e não podem ter implementações de métodos. Note que a partir do Java 8 em diante, podemos criar métodos padrão e estáticos em interfaces que contêm implementações de métodos.
- Classes abstratas podem ter construtores, mas interfaces não podem ter construtores.
- Classes abstratas possuem todas as características de uma classe Java normal, exceto que não podemos instanciá-las. Podemos usar a palavra-chave
abstract
para tornar uma classe abstrata, mas interfaces são um tipo completamente diferente e podem ter apenas constantes públicas estáticas finais e declarações de métodos. - Os métodos de classes abstratas podem ter modificadores de acesso como público, privado, protegido, estático, mas os métodos de interface são implicitamente públicos e abstratos, não podemos usar outros modificadores de acesso com métodos de interface.
- A subclass can extend only one abstract class but it can implement multiple interfaces.
- Classes abstratas podem estender outras classes e implementar interfaces, mas interfaces só podem estender outras interfaces.
- Podemos executar uma classe abstrata se ela tiver um método
main()
, mas não podemos executar uma interface porque elas não podem ter implementação de método principal. - Interfaces são usadas para definir contrato para as subclasses, enquanto classes abstratas também definem contrato, mas podem fornecer implementações de outros métodos para as subclasses usarem.
Isso é tudo para a diferença entre uma interface e classes abstratas, agora podemos passar a saber quando devemos usar Interface em vez de Classe Abstrata e vice-versa.
Interface ou Classe Abstrata
A escolha entre Interface ou classe abstrata para fornecer um contrato para subclasses é uma decisão de design e depende de muitos fatores. Vamos ver quando as Interfaces são a melhor escolha e quando podemos usar classes abstratas.
- O Java não suporta herança de nível de classe múltipla, então cada classe pode estender apenas uma superclasse. Mas uma classe pode implementar várias interfaces. Portanto, na maioria das vezes, as Interfaces são uma boa escolha para fornecer a base para a hierarquia de classes e contrato. Além disso, programar em termos de interfaces é uma das melhores práticas para codificação em Java.
- Se houver muitos métodos no contrato, então a classe abstrata é mais útil, pois podemos fornecer uma implementação padrão para alguns dos métodos que são comuns a todas as subclasses. Além disso, se as subclasses não precisarem implementar um método específico, elas podem evitar fornecer a implementação. No caso da interface, a subclasse terá que fornecer a implementação para todos os métodos, mesmo que não seja útil e a implementação seja apenas um bloco vazio.
- Se nosso contrato base estiver sempre mudando, as interfaces podem causar problemas porque não podemos declarar métodos adicionais na interface sem alterar todas as classes de implementação. Com a classe abstrata, podemos fornecer a implementação padrão e alterar apenas as classes de implementação que realmente utilizarão os novos métodos.
Use de classes abstratas e interfaces simultaneamente
Usar interfaces e classes abstratas juntas é a melhor abordagem para projetar um sistema. Por exemplo, no JDK, java.util.List
é uma interface que contém muitos métodos. Portanto, existe uma classe abstrata, java.util.AbstractList
, que fornece uma implementação esquelética para todos os métodos da interface List, de modo que qualquer subclasse pode estender essa classe e implementar apenas os métodos necessários. Devemos sempre começar com uma interface como base e definir métodos que toda subclasse deve implementar. Se houver métodos que apenas determinada subclasse deve implementar, podemos estender a interface base e criar uma nova interface com esses métodos. As subclasses terão a opção de escolher entre a interface base ou a interface filha para implementar de acordo com seus requisitos. Se o número de métodos aumentar muito, não é uma má ideia fornecer uma classe abstrata esquelética implementando a interface filha e dando flexibilidade às subclasses para escolher entre a interface e uma classe abstrata.
Java 8 – Mudanças em interfaces
A partir do Java 8, podemos ter implementações de métodos nas interfaces. Podemos criar métodos padrão e estáticos nas interfaces e fornecer uma implementação para eles. Isso eliminou a diferença entre classes abstratas e interfaces, e agora as interfaces são o caminho a seguir, pois podemos estendê-las ainda mais fornecendo implementações padrão para novos métodos. Para mais detalhes, confira Métodos estáticos padrão de interface Java 8.