1. Classe base comum
Hoje vamos desfrutar de uma miscelânea de tópicos interessantes. Lembra quando introduzimos a ChessItem
classe 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 ChessItem
classe 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 ChessItem
classe 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 ChessItem
objetos 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
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 abstract
palavra-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 abstract
palavra-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 |
---|---|
|
Este código não compila : |
|
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 private
modificador. 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.
GO TO FULL VERSION