"Olá, amigo! Temos um novo tópico fascinante."

"Hoje é apenas um dia de tópicos fascinantes!"

"Ora, obrigado!"

"De nada."

"Lembra quando introduzimos a classe base ChessItem para simplificar todas as classes de peças de xadrez?"

"Sim."

"Agora imagine que cada peça tem um método que lida com a renderização da peça na tela. Você chama o método e a peça se desenha em suas coordenadas atuais. Seria útil mover esse método para a classe base?"

"Sim." Depois de aprender sobre polimorfismo, seria capaz de chamar o método render para todas as peças, independentemente do tipo. Algo assim:"

Por exemplo:
class ChessBoard
{
  public void drawAllChessItems()
  {
  //draw them regardless of their type.
  ArrayList <ChessItem> items = new ArrayList<ChessItem>();
  items.add(new King());
  items.add(new Queen());
  items.add(new Bishop());

  //draw them regardless of their type.
  for (ChessItem item: items)
  {
   item.draw();
  }
 }
}

"Muito bem. Exatamente. E o que seria feito pelo método draw da própria classe ChessItem?"

"Não sei. O xadrez não tem essa peça. E isso significa que não tem representação visual."

"Exatamente. E não faz sentido criar um objeto ChessItem. Não existe essa peça de xadrez. É apenas uma abstração - uma classe que criamos por conveniência. É assim que a abstração funciona em OOP: movemos todas as peças importantes (compartilhadas por todas as peças) dados e métodos em uma classe base , mas mantivemos suas diferenças nas classes correspondentes a peças de xadrez específicas."

Java tem um tipo de classe especial para isso: a classe abstrata . Aqui estão três coisas para lembrar sobre classes abstratas.

1) Uma classe abstrata pode declarar métodos sem implementá-los. Tal método é chamado de método abstrato.

Por exemplo:
 public abstract class ChessItem
{
 public int x, y; //coordinates
 private int value; //the piece's "value"

 public int getValue() //an ordinary method, returns value
 {
   return value;
 }

 public abstract void draw(); //abstract method. There is no implementation.

}

2) Um método abstrato é marcado com a palavra-chave abstract .

Se uma classe tiver pelo menos um método abstrato, a classe também será marcada com abstract .

3) Você não pode criar objetos de uma classe abstrata. O código que tenta fazer isso simplesmente não compila.

código Java Descrição
ChessItem item = new ChessItem();
item.draw();
Este código não compila.
ChessItem item = new Queen();
item.draw();
Mas você pode fazer isso.

4) Se sua classe herda uma classe abstrata, você precisa substituir todos os métodos abstratos herdados, ou seja, você deve implementá-los. Caso contrário, sua classe também terá que ser declarada abstrata. Se a classe tiver pelo menos um método não implementado declarado diretamente na classe ou herdado da classe pai, a classe será considerada abstrata.

"Mas por que tudo isso é necessário? Por que precisamos de classes abstratas? Não é possível usar classes comuns? E, em vez de métodos abstratos, não podemos simplesmente criar implementações vazias que consistem em abrir e fechar colchetes?"

"Você poderia. Mas essas restrições são como o privatemodificador. Usamos o privatemodificador para bloquear deliberadamente o acesso direto aos dados, para que outros programadores e suas classes usem nossos publicmétodos."

O mesmo se aplica a uma classe abstrata. Quem escreveu a classe não quer que ninguém crie instâncias da classe. Pelo contrário, o autor espera que os métodos abstratos de sua classe abstrata sejam herdados e substituídos.

"Ainda não entendo por que queremos complicar nossas vidas dessa maneira."

"A vantagem desse recurso é evidente em grandes projetos. Quanto mais classes você tiver, mais claramente precisará delinear seus papéis. Você verá a vantagem de fazer isso, e logo. Todo mundo tem que passar por isso."