Classes Abstratas
Em Java, temos um tipo especial de classe chamado classe abstrata. Este tipo de classe possui uma característica muito específica, que é o de não permitir que novos objetos sejam instanciados a partir desta classe. Por este motivo, as classes abstratas possuem o único propósito de servirem como super classes a outras classes do Java.
Em Java definimos uma classe como abstrata utilizando a palavra-chave abstract
na declaração da classe. No vídeo a seguir mostramos passo a passo como funciona a classe abstrata:
Vamos praticar mais um pouco, veja este outro exemplo do uso de classe abstrata:
Na linha 6 estamos criando uma classe abstrata através da palavra-chave abstract
.
Uma classe abstrata é desenvolvida para representar entidades e conceitos abstratos, sendo utilizada como uma classe pai, pois não pode ser instanciada. Ela define um modelo (template) para uma funcionalidade e fornece uma implementação incompleta - a parte genérica dessa funcionalidade - que é compartilhada por um grupo de classes derivadas. Cada uma das classes derivadas completa a funcionalidade da classe abstrata adicionando um comportamento específico.
Uma classe abstrata normalmente possui métodos abstratos. Esses métodos são implementados nas suas classes derivadas concretas com o objetivo de definir o comportamento específico. O método abstrato define apenas a assinatura do método e, portanto, não contém código assim como feito nas Interfaces.
Uma classe abstrata pode também possuir atributos e métodos implementados, componentes estes que estarão integralmente acessíveis nas subclasses, a menos que o mesmo seja do tipo private
.
Como todo método abstrato precisa ser implementado pela classe filha, então não pode ser private, pois não seria visível na subclasse.
Neste exemplo, criaremos uma classe abstrata chamada Tela
. Nesta classe implementaremos alguns métodos que devem ser utilizados por todas as telas do computador de bordo de um veículo, como: setTitulo()
para informar o título da tela e imprimir()
, que imprime as informações na tela.
Nesta classe definiremos também a assinatura de um método abstrato chamado obterInformacao()
, que deve ser implementado pelas classes filhas.
Agora criaremos a classe TelaKilometragem
, que será uma subclasse da classe abstrata Tela
. Esta classe será utilizada para mostrar a km atual percorrida pelo veículo.
Vamos, agora, criar uma classe para testar a nossa aplicação. Neste teste, criaremos um objeto da classe TelaKilometragem
e chamar o método imprimir()
, que esta classe herdou da classe Tela
.
Quando definimos Tela tk = new TelaKilometragem()
, estamos guardando um objeto do tipo TelaKilometragem
dentro de uma variável do tipo Tela
. Podemos fazer isso porque toda TelaKilometragem
é uma subclasse de Tela
.
Quando chamamos o método tk.imprimir()
, estamos chamando o método que foi implementado na classe abstrata Tela, mas note que o método imprimir()
usa o método obterInformacao()
, que foi implementado na classe TelaKilometragem
. Em tempo de execução, a JVM verifica o tipo do objeto e chama o método que foi implementado nele, isto chama-se Polimorfismo.
Temos a seguinte saída no console:
Segue abaixo um quadro comparativo entre Interface e Classe Abstrata:
Classe Abstrata | Interface |
Pode possui atributos de instância | Possui apenas constantes |
Possui métodos de diversas visibilidade e métodos implementados ou abstratos | Todos os métodos são public e abstract |
É estendida por classes (sub-classes) | É implementada por classes |
Uma subclasse só pode estender uma única classe abstrata | Uma classe pode implementar mais de uma interface |
Hierarquia de herança com outras classes abstratas | Hierarquia de herança com outras interfaces |