Em Java, tanto as classes abstratas quanto as interfaces são mecanismos cruciais para a abstração. A abstração, no contexto da programação orientada a objetos, visa ocultar os detalhes de implementação dos utilizadores finais, apresentando-lhes apenas o essencial.
Através da abstração, um utilizador tem conhecimento das funcionalidades disponíveis, mas não se aprofunda na complexidade da sua implementação.
Vamos agora analisar cada um destes conceitos para compreender a sua finalidade e utilidade.
Classe Abstrata
Uma classe abstrata em Java é aquela que não pode ser diretamente instanciada como um objeto. Pode conter métodos abstratos, que são aqueles que não possuem uma implementação no momento da declaração.
Um exemplo clássico é a classe abstrata ‘GraphicObject’ da Oracle.
Para definir uma classe como abstrata, utiliza-se a palavra-chave ‘abstract’ antes da palavra-chave ‘class’.
abstract class ClasseAbstrata { void executar() { System.out.println("executado"); } }
Classes abstratas servem como bases para outras classes, o que significa que podem ser estendidas ou especializadas por subclasses.
abstract class ClasseAbstrata { void executar() { System.out.println("executado"); } } class SubClasse extends ClasseAbstrata { void novoMetodo() { System.out.println("novo"); } @Override void executar() { System.out.println("sobrescrito"); } }
As classes abstratas são particularmente úteis para implementar métodos comuns entre várias classes que a herdam. A capacidade de declarar métodos abstratos torna-as indispensáveis para classes com métodos semelhantes, mas implementações diferentes. Vejamos um exemplo prático.
Considere a classe ‘Carro’, que possui funcionalidades como ligar, parar, dar ré, etc. Estas funcionalidades são comuns a todos os carros.
No entanto, funcionalidades como a condução autónoma podem variar consideravelmente entre os diferentes tipos de carros. Vamos criar um programa orientado a objetos para ilustrar essa situação.
Começamos por criar uma classe base chamada ‘Carro’, que será estendida por diferentes tipos de carros.
abstract class Carro { void ligar() { // implementação System.out.println("carro em funcionamento"); } void parar() { // implementação System.out.println("motor parado"); } void re() { // implementação System.out.println("modo de ré ativado"); } abstract void conduzirAutonomamente(); }
Os métodos ‘ligar()’, ‘parar()’ e ‘re()’ são métodos genéricos que já estão implementados na classe ‘Carro’. Por outro lado, o método ‘conduzirAutonomamente()’ é declarado como abstrato, permitindo que cada tipo de carro defina a sua própria implementação.
class CarroTipoA extends Carro { @Override void ligar() { super.ligar(); } @Override void parar() { super.parar(); } @Override void re() { super.re(); } void conduzirAutonomamente() { // implementação personalizada System.out.println("Modo de condução autónoma do Tipo A ativado"); } }
class CarroTipoB extends Carro { // ...métodos semelhantes void conduzirAutonomamente() { // implementação personalizada System.out.println("Modo de condução autónoma do Tipo B ativado"); } }
Importante: se uma subclasse não implementar todos os métodos abstratos da classe abstrata, ela própria deverá ser definida como abstrata.
Interface
Uma interface é um contrato que define os métodos que uma classe deve implementar. Tomando o exemplo do carro, ele deve ter a capacidade de ligar, mover e parar. Estas são funções básicas que todos os carros devem suportar.
Se uma classe implementar a interface ‘Carro’, será obrigada a definir todos os métodos para garantir o seu correto funcionamento e segurança.
De maneira similar às classes abstratas, as interfaces não podem ser instanciadas. São consideradas totalmente abstratas, pois contêm apenas métodos abstratos (sem corpo de implementação).
Para declarar uma interface, usa-se a palavra-chave ‘interface’.
interface CARRO { void ligar(); void parar(); void mover(); }
Uma classe implementa uma interface usando a palavra-chave ‘implements’.
class CarroTipoB implements CARRO { public void ligar() { System.out.println("ligado"); } public void parar() { System.out.println("parado"); } public void mover() { System.out.println("a andar"); } }
Semelhanças
A principal semelhança entre classes abstratas e interfaces é a impossibilidade de criar instâncias diretas.
Diferenças
Classe Abstrata | Interface | |
Herança/Implementação | Apenas uma classe abstrata pode ser herdada por uma classe. | Múltiplas interfaces podem ser implementadas por uma classe. |
Tipos de Variáveis | Pode conter variáveis finais, não finais, estáticas e não estáticas. | Pode conter apenas variáveis estáticas e finais. |
Tipos de Métodos | Pode conter métodos abstratos e não abstratos. | Pode conter apenas métodos abstratos, com exceção de métodos estáticos. |
Modificadores de Acesso | Uma classe abstrata pode ter modificadores de acesso. | As assinaturas de método definidas na interface são públicas por padrão. Uma interface não tem modificador de acesso. |
Construtores e Destrutores | Pode declarar construtores e destrutores. | Não pode declarar construtores ou destrutores. |
Velocidade | Rápida | Lenta |
Estas são as principais diferenças entre classes abstratas e interfaces.
Quando usar classe abstrata e interface?
Utilize classes abstratas quando:
- Necessita partilhar métodos e atributos comuns entre várias classes.
- Precisa declarar campos não estáticos e não finais para modificar o estado de objetos.
Utilize interfaces quando:
- Pretende definir o comportamento de uma classe, mas não a forma como a implementação é feita.
- Quer garantir que uma classe implementa todos os métodos necessários para funcionar corretamente.
Considerações Finais
As interfaces são frequentemente usadas para criar APIs, pois fornecem uma estrutura para implementar funcionalidades sem preocupações com a implementação detalhada.
As classes abstratas são ideais para partilhar métodos abstratos e não abstratos entre várias classes que herdam a classe abstrata, promovendo a reutilização de código.
Se desejar aprofundar os seus conhecimentos em Java, explore os diversos cursos online disponíveis. Está a preparar-se para uma entrevista em Java? Consulte algumas perguntas frequentes sobre Programação Orientada a Objetos.