1. Classe de base commune

Aujourd'hui, nous allons profiter d'un assortiment de sujets intéressants. Vous vous souvenez quand nous avons introduit la ChessItemclasse de base pour simplifier toutes les classes représentant des pièces d'échecs ? Je l'espère 🙂

Imaginez maintenant que chaque pièce a une draw()méthode qui gère son dessin à l'écran. Vous appelez la draw()méthode et la pièce se dessine à ses coordonnées actuelles. Il serait pratique de déplacer cette méthode vers la classe de base.

Si la draw()méthode était dans la classe de base ChessItem, alors nous pourrions la remplacer dans les classes de pièces et écrire un code élégant comme celui-ci :

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();
      }
   }
}

En introduisant la ChessItemclasse de base, nous avons pu grandement simplifier le code : il n'est pas nécessaire d'appeler les méthodes de chaque classe séparément, on peut facilement stocker tous les objets dans une seule collection, etc.

Mais voici une question intéressante : que doit dessiner à l'écran la draw()méthode déclarée directement dans la classe ? ChessItemAprès tout, il n'y a pas une telle pièce aux échecs, donc il n'y a rien à tirer.

C'est exactement ça. De plus, cela n'a aucun sens de créer ChessItemdirectement des objets. Ce n'est pas une pièce d'échecs, mais plutôt une abstraction - une classe que nous avons créée pour notre commodité. C'est ainsi que fonctionne l'abstraction en POO : nous déplaçons les données et méthodes importantes (celles partagées par tous les morceaux) vers une classe de base, et conservons leurs différences dans des classes descendantes distinctes.


2. Classes abstraites

Cours abstraits

Pour de telles situations, Java a un type spécial de classe : la classe abstraite . Ils sont conçus pour permettre aux programmeurs de travailler plus facilement avec des classes similaires et de réduire la quantité de code dupliqué qu'ils contiennent.

Voici trois choses à savoir sur les classes abstraites.

Méthode sans implémentation

Une classe abstraite peut avoir une déclaration de méthode sans implémentation. C'est exactement ce qui rend la méthode abstraite. Le corps de la méthode est simplement remplacé par un point-virgule. Et avant le nom de la méthode, nous écrivons le abstractmot-clé. Exemple:

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 abstraite

Chaque méthode sans implémentation est marquée avec le mot-clé abstract. Si une classe a ne serait-ce qu'une seule méthode abstraite, la classe est également marquée avec le abstractmot-clé.

Interdire la création d'objets

Vous ne pouvez pas créer d'objets d'une classe abstraite . Un tel code ne compilera tout simplement pas.

Code Description
ChessItem item = new ChessItem();
item.draw();
Ce code ne compile pas :
ChessItem item = new Queen();
item.draw();
Mais tu peux faire ça

Héritage d'une classe abstraite

Si votre classe hérite d'une classe abstraite, vous devez remplacer toutes les méthodes abstraites héritées, c'est-à-dire que vous devez écrire une implémentation pour elles. Sinon, votre classe elle-même devra également être déclarée abstraite.

Si une classe a ne serait-ce qu'une seule méthode non implémentée déclarée directement ou héritée d'une classe parente, alors la classe est considérée comme abstraite.

Et pourquoi tout cela est-il nécessaire ? Pourquoi les classes abstraites sont-elles nécessaires ? N'est-il pas possible d'utiliser des modèles ordinaires à la place ? Et au lieu de méthodes abstraites, ne pourrions-nous pas simplement écrire deux accolades vides comme corps de la méthode ?

Nous pourrions. Mais ces restrictions s'apparentent au privatemodificateur. Nous utilisons le mot clé private pour empêcher délibérément d'autres programmeurs d'accéder directement aux données et pour les forcer à n'utiliser que nos méthodes publiques lors de l'écriture de leurs classes.

C'est la même chose avec les classes abstraites. L'auteur d'une classe abstraite ne veut pas que les objets de la classe soient créés. Au lieu de cela, l'auteur s'attend à ce que les méthodes abstraites soient héritées de la classe abstraite, puis remplacées.

L'avantage de cette approche est évident dans les grands projets. Plus vous avez de classes, plus vous devez définir clairement leurs rôles. Vous verrez l'avantage de cette approche dans un avenir proche. Tout passe par là.