1. Classe base comum

Hoje vamos desfrutar de uma miscelânea de tópicos interessantes. Lembra quando introduzimos a ChessItemclasse base para simplificar todas as classes que representam peças de xadrez? Espero que sim 🙂

Agora imagine que cada peça tem um draw()método que trata de desenhá-la na tela. Você chama o draw()método e a peça se desenha em suas coordenadas atuais. Seria conveniente mover esse método para a classe base.

Se o draw()método estivesse na classe base ChessItem, poderíamos substituí-lo nas classes de peças e escrever um código elegante como este:

class ChessBoard
{
   public void drawAllChessItems()
   {
      // Add the pieces to the list
      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();
      }
   }
}

Ao introduzir a ChessItemclasse base, conseguimos simplificar bastante o código: não há necessidade de chamar os métodos de cada classe separadamente, podemos facilmente armazenar todos os objetos em uma única coleção, etc.

Mas aqui está uma pergunta interessante: o que o draw()método declarado diretamente na ChessItemclasse deve desenhar na tela? Afinal, não existe tal peça no xadrez, então não há nada para desenhar.

Isso é exatamente certo. Além do mais, não faz sentido criar ChessItemobjetos diretamente. Não é uma peça de xadrez, mas apenas uma abstração — uma classe que criamos para nossa conveniência. É assim que a abstração funciona em OOP : movemos dados e métodos importantes (aqueles compartilhados por todas as partes) para uma classe base e mantemos suas diferenças em classes descendentes separadas.


2. Aulas abstratas

aulas abstratas

Para tais situações, Java possui um tipo especial de classe: a classe abstrata . Eles são projetados para facilitar o trabalho dos programadores com classes semelhantes e reduzir a quantidade de código duplicado nelas.

Aqui estão três coisas que você deve saber sobre classes abstratas.

Método sem implementação

Uma classe abstrata pode ter uma declaração de método sem uma implementação. Isso é exatamente o que torna o método abstrato. O corpo do método é simplesmente substituído por um ponto e vírgula. E antes do nome do método, escrevemos a abstractpalavra-chave. Exemplo:

public abstract class ChessItem
{
   public int x, y; // Coordinates
   private int value; // The piece's value
   public int getValue() // Ordinary method that returns value field
   {
      return value;
   }

   public abstract void draw(); // Abstract method. The implementation is missing.
}

classe abstrata

Cada método sem uma implementação é marcado com a palavra-chave abstract. Se uma classe tiver pelo menos um método abstrato, a classe também será marcada com a abstractpalavra-chave.

Proibindo a criação de objetos

Você não pode criar objetos de uma classe abstrata . Esse código simplesmente não compila.

Código 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

Herdando uma classe abstrata

Se sua classe herda uma classe abstrata, então você precisa substituir todos os métodos abstratos herdados, ou seja, você precisa escrever uma implementação para eles. Caso contrário, sua própria classe também terá que ser declarada abstrata.

Se uma classe tiver pelo menos um método não implementado declarado diretamente nela ou herdado de uma classe pai, a classe será considerada abstrata.

E por que tudo isso é necessário? Por que as classes abstratas são necessárias? Não é possível usar os comuns? E em vez de métodos abstratos, não poderíamos simplesmente escrever duas chaves vazias como o corpo do método?

Poderíamos. Mas essas restrições são semelhantes ao privatemodificador. Usamos a palavra-chave private para impedir deliberadamente que outros programadores acessem dados diretamente e para forçá-los a usar apenas nossos métodos públicos ao escrever suas classes.

É o mesmo com classes abstratas. O autor de uma classe abstrata não deseja que os objetos da classe sejam criados. Em vez disso, o autor espera que os métodos abstratos sejam herdados da classe abstrata e depois substituídos.

A vantagem dessa abordagem é facilmente aparente em grandes projetos. Quanto mais classes você tiver, mais claramente precisará delinear seus papéis. Você verá os benefícios dessa abordagem em um futuro próximo. Tudo passa por isso.