Outils pour utilisateurs

Outils du site


java:abstract

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
java:abstract [2013/11/07 14:27] – [Un peu de théorie histoire de bien situer le contexte] brunojava:abstract [2018/03/16 15:42] (Version actuelle) – [Pour aller encore plus loin: les classes virtuelles pures (ou interfaces en java)] bruno
Ligne 1: Ligne 1:
 ====== Abstract et java ====== ====== Abstract et java ======
 +
 +> "Le concret c'est de l'abstrait rendu familier par l'usage." (Paul Longevin)
 +
 Nous voyons aujourd'hui dans ce TP guidé un concept qui porte malheureusement bien souvent son nom: **abstract**. Nous voyons aujourd'hui dans ce TP guidé un concept qui porte malheureusement bien souvent son nom: **abstract**.
  
-En effet, très souvent, les débutants en java et plus généralement en objet ne comprennent pas à quoi il sert, et donc l'utilise à tord et à travers.+En effet, très souvent, les débutants en java et plus généralement en objet ne comprennent pas à quoi il sert, et donc l'utilisent à tord et à travers.
  
 Heureusement, dans 30 minutes maximum, vous constaterez que c'est en réalité **très** simple! Heureusement, dans 30 minutes maximum, vous constaterez que c'est en réalité **très** simple!
Ligne 8: Ligne 11:
 C'est parti! C'est parti!
  
-===== Un peu de théorie histoire de bien situer le contexte =====+===== Un peu de théorie histoire de bien situer la problématique =====
  
-Je vais commencer par un peu de théorie de la programmation orientée objet.+> Plus abstraite est la vérité que tu veux enseigner, plus tu dois en sa faveur séduire les sens. (Friedrich Nietzsche) 
 +  
 +Je vais commencer par essayer de vous séduire avec un peu de théorie de la programmation orientée objet (certain diront que c'est pas gagné d'avance, mais j'aimerais bien voir Nietzsche à ma place ;-)).
  
 Vous savez normalement ce qu'est l'héritage. Ce concept est directement lié à l'utilisation de //abstract//. Vous savez normalement ce qu'est l'héritage. Ce concept est directement lié à l'utilisation de //abstract//.
Ligne 18: Ligne 23:
 Ces classes mères permettent avant tout de donner une direction générale à la programmation, au //modèle//, mais ne peuvent pas toujours tout prévoir. Ces classes mères permettent avant tout de donner une direction générale à la programmation, au //modèle//, mais ne peuvent pas toujours tout prévoir.
  
-Nous savons qu'il est possible de //redéfinir// des comportements (par exemple, //toString()//, //equals()//, etc.+Nous savons qu'il est possible de //redéfinir// des comportements (par exemple, //toString()//, //equals()//, etc.).
  
 Mais pour l'instant, nous ne savons pas encore comment contraindre les héritiers à préciser leur comportement en redéfinissant des méthodes. Mais pour l'instant, nous ne savons pas encore comment contraindre les héritiers à préciser leur comportement en redéfinissant des méthodes.
Ligne 24: Ligne 29:
 Nous allons voir ici que justement, la programmation objet permet de résoudre ces problèmes. Nous allons voir ici que justement, la programmation objet permet de résoudre ces problèmes.
  
-Nous allons découvrir trois manières de traiter l'abstraction en programmation orientée objet:+Nous allons découvrir trois manières de traiter l'abstraction en programmation orientée objet, et plus précisément avec java:
   - les classes abstraites;   - les classes abstraites;
   - les méthodes virtuelles (ou abstraites);   - les méthodes virtuelles (ou abstraites);
Ligne 162: Ligne 167:
 </code> </code>
  
-==== Les classes abstraites ====+===== Les classes abstraites =====
 Dans la hiérarchie que je viens de donner, il n'est pas très utile d'utiliser le constructeur //Animal//: en effet, la classe Animal sert uniquement à regrouper ce qu'il y a de commun entre des héritiers (Chat, Chien, Souris, etc.). Dans la hiérarchie que je viens de donner, il n'est pas très utile d'utiliser le constructeur //Animal//: en effet, la classe Animal sert uniquement à regrouper ce qu'il y a de commun entre des héritiers (Chat, Chien, Souris, etc.).
  
Ligne 224: Ligne 229:
 On voit bien que c'est l'utilisation du constructeur //Animal// avec **new** qui rend impossible la création directe d'instances d'//Animal//. On voit bien que c'est l'utilisation du constructeur //Animal// avec **new** qui rend impossible la création directe d'instances d'//Animal//.
  
-==== Allons un peu plus loin: les méthodes virtuelles (ou abstraites) ====+===== Allons un peu plus loin: les méthodes virtuelles (ou abstraites) =====
  
 Nous avons vu que nous pouvions interdire la création directe d'instances d'une classe lorsque celle-ci n'est pas "intéressante" en tant qu'objet, mais utile pour des raisons de regroupement hiérarchique. Nous avons vu que nous pouvions interdire la création directe d'instances d'une classe lorsque celle-ci n'est pas "intéressante" en tant qu'objet, mais utile pour des raisons de regroupement hiérarchique.
Ligne 235: Ligne 240:
  
 **Hé bien c'est possible!** Nous allons déclarer //jouer// comme étant une méthode //virtuelle// dans la classe Animal. **Hé bien c'est possible!** Nous allons déclarer //jouer// comme étant une méthode //virtuelle// dans la classe Animal.
 +
 +==== Les méthodes virtuelles ou méthodes abstraites ====
  
 Une méthode //virtuelle//: Une méthode //virtuelle//:
Ligne 464: Ligne 471:
  
 </code> </code>
 +
 +==== Et si je ne veux pas redéfinir une méthode abstraite, hein? ====
 +
 +Vous vous posez peut-être cette question.
 +
 +Hé bien, c'est possible! Mais pas à n'importe quel prix!
 +
 +Les chats sont paresseux, supposons que la classe Chats ne redéfinisse pas la méthode jouer.
 +
 +Que va dire le compilateur? Essayons pour voir! Commentez la méthode jouer dans Chat
 +
 +<code java>
 + /**
 + Pour faire jouer le chat.
 + Affiche un petit message en console.
 + @param a l'animal qui veut jouer avec this
 + @return true si l'animal veut bien jouer avec a
 + */
 + /* Je veux pas redéfinir moi!
 + public boolean jouer(Animal a){
 + boolean ret = true;
 + String message = "Je veux bien jouer avec les instances de " + a.getClass().getName() ;
 + if(a instanceof Chien){
 + ret=false;
 + message = "Je ne joue pas avec les chiens, moi!";
 + }
 + System.out.println(message);
 + return ret;
 + }
 + */
 +</code>
 +
 +Recompilons:
 +
 +<code bash>
 +./Chat.java:22: error: Chat is not abstract and does not override abstract method jouer(Animal) in Animal
 +public class Chat extends Animal{
 +</code>
 +
 +Apparemment, le compilateur semble contrarié. Regardons en détail ce qu'il nous raconte:
 +
 +> "Chat n'est pas abstract" -> ok
 +
 +> "...et ne redéfinit pas la méthode abstraite jouer(Animal)" -> on vient de la commenter...
 +
 +Quel problème cela pose-t-il pour le compilateur: raisonnons par l'absurde.
 +
 +Si le compilateur permettait à Chat de ne **pas** redéfinir la méthode jouer, et également de construire des instances de Chat, que se passerait-il lorsque l'on voudrait appeler la méthode //jouer(Animal)// sur une instance de Chat?
 +
 +Il n'y aurait pas de code défini -> le programme ne saurait pas quoi faire.
 +
 +Le "contrat" donné par //Animal// est que toute instance d'Animal doit pourvoir //jouer// et //manger//.
 +
 +Donc, si ce comportement n'est pas définit dans un héritier d'Animal (Chat), alors il n'est pas possible de créer des instances de //Chat//.
 +
 +Le compilateur propose donc deux solutions:
 +  - soit passer la classe Chat en classe abstraite, afin d'empêcher l'utilisation du constructeur Chat directement;
 +  - soit redéfinir la méthode //jouer// dans Chat, pour permettre la construction d'instances de Chat.
 +
 +Si on choisit la première solution, Chat devient abstract et il n'y a plus de problème de compilation... à condition de ne pas utiliser le constructeur //Chat// avec **new**.
 +
 +Si une classe hérite de Chat (par exemple //ChatJoueur//) et que le programmeur veut créer des instances de //ChatJoueur//, il devra alors redéfinir la méthode //jouer// héritée de Animal par l'intermédiaire de //Chat// dans la classe //ChatJoueur//: on appelle ça "refiler la patate chaude".
 +
 +===== Pour aller encore plus loin: les classes virtuelles pures (ou interfaces en java) =====
 +
 +-> ce dernier point fait l'objet d'un autre TP guidé...
 +
  
java/abstract.1383834437.txt.gz · Dernière modification : 2013/11/07 14:27 de bruno