Olá Alisson,
Vamos considerar o seguinte exemplo:
public abstract class Funcionario {
public abstract double getBonificacao();
public void mostraBonificacao() {
System.out.println(getBonificacao());
}
Nesse caso, se conseguíssemos instanciar a classe Funcionario
, o que aconteceria se tentássemos invocar o método mostraBonificacao()
?
Teríamos um problema porque o funcionario não tem o método getBonificacao()
implementado! Por isso, quando temos pelo menos um método abstrato em nossas classes, temos que torná-la abstrata. Fazendo isso, agora não conseguimos mas instanciar a classe Funcionario
e não precisamos nos preocupar com o problema citado acima.
Mas e se tivermos classes que herdam de Funcionario
? Por exemplo, um Gerente
:
public class Gerente extends Funcionario {
...
}
Como a classe Funcionario
tem um método abstrato, o Gerente
será forçado a implementá-lo:
public class Gerente extends Funcionario {
public double getBonificacao() {
return 500.0;
}
}
Agora, o que vai acontecer quando invocarmos o método mostraBonificacao()
no Gerente
?
Nesse caso não temos problema algum! O método mostraBonificacao()
agora só pode ser invocado em classes que herdam de Funcionario
(ele é abstrato). Todas as classes que herdam de Funcionario
precisam implementar o getBonificacao()
. Logo, quando invocarmos o mostraBonificacao()
, o método getBonificacao()
sempre vai existir!
A vantagem de fazer isso é que conseguimos deixar um comportamento padrão para todos funcionários na classe Funcionario
(mostraBonificacao) e deixamos a parte que pode variar de acordo com o cargo (getBonificacao) para que seja implementada nas subclasses do Funcionario
.
Dessa forma podemos implementar algoritmos bem complexos em uma classe base e permitir que partes desse algoritmo sejam customizadas nas classes filhas.
Espero ter ajudado!