java:abstract
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
java:abstract [2013/11/07 13:43] – créée bruno | java: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' | ||
+ | |||
Nous voyons aujourd' | Nous voyons aujourd' | ||
- | 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 | + | 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 |
Heureusement, | Heureusement, | ||
Ligne 8: | Ligne 11: | ||
C'est parti! | C'est parti! | ||
- | ===== Un peu de théorie histoire de bien situer | + | ===== Un peu de théorie histoire de bien situer |
- | 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' | ||
Vous savez normalement ce qu'est l' | Vous savez normalement ce qu'est l' | ||
+ | |||
+ | Or, bien souvent, il est délicat d' | ||
+ | |||
+ | Ces classes mères permettent avant tout de donner une direction générale à la programmation, | ||
+ | |||
+ | Nous savons qu'il est possible de // | ||
+ | |||
+ | Mais pour l' | ||
+ | |||
+ | 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' | ||
+ | - les classes abstraites; | ||
+ | - les méthodes virtuelles (ou abstraites); | ||
+ | - les classes virtuelles pures (ou interface en java). | ||
+ | |||
+ | ===== Passons à la pratique! ===== | ||
+ | |||
Prenons un premier exemple simple: mon sujet d' | Prenons un premier exemple simple: mon sujet d' | ||
Ligne 144: | Ligne 167: | ||
</ | </ | ||
- | ==== Les classes abstraites ==== | + | ===== Les classes abstraites |
Dans la hiérarchie que je viens de donner, il n'est pas très utile d' | Dans la hiérarchie que je viens de donner, il n'est pas très utile d' | ||
Ligne 206: | Ligne 229: | ||
On voit bien que c'est l' | On voit bien que c'est l' | ||
- | ==== 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' | Nous avons vu que nous pouvions interdire la création directe d' | ||
Ligne 217: | Ligne 240: | ||
**Hé bien c'est possible!** Nous allons déclarer //jouer// comme étant une méthode // | **Hé bien c'est possible!** Nous allons déclarer //jouer// comme étant une méthode // | ||
+ | |||
+ | ==== Les méthodes virtuelles ou méthodes abstraites ==== | ||
Une méthode // | Une méthode // | ||
Ligne 226: | Ligne 251: | ||
{{ : | {{ : | ||
- | Et voici le code correspondant à cette modification. Il implémente la fonctionnalité demandée sur le comportement " | + | Et voici le code correspondant à cette modification. Il implémente la fonctionnalité demandée sur le comportement " |
+ | |||
+ | <code java Animal.java> | ||
+ | /** | ||
+ | Une toute petite classe représentant un Animal | ||
+ | | ||
+ | */ | ||
+ | public abstract class Animal{ | ||
+ | /**le nom de l' | ||
+ | private String nom =""; | ||
+ | /** l' | ||
+ | private String espece=""; | ||
+ | |||
+ | /** | ||
+ | Constructeur d' | ||
+ | @param n valeur pour nom | ||
+ | @param e valeur pour espece | ||
+ | */ | ||
+ | public Animal(String n, String e){ | ||
+ | nom = n; | ||
+ | espece = e; | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | Constructeur d' | ||
+ | L' | ||
+ | @param n valeur pour nom | ||
+ | */ | ||
+ | public Animal(String n){ | ||
+ | nom = n; | ||
+ | espece = " | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | Pour faire jouer l' | ||
+ | Affiche un petit message en console. | ||
+ | @param a l' | ||
+ | @return true si l' | ||
+ | */ | ||
+ | public abstract boolean jouer(Animal a); | ||
+ | /*pas de corps pour une méthode abstraite | ||
+ | { | ||
+ | boolean ret = true; | ||
+ | System.out.println(" | ||
+ | return ret; | ||
+ | }*/ | ||
+ | |||
+ | public void manger(){ | ||
+ | System.out.println(" | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java Chien.java> | ||
+ | /** | ||
+ | Une toute petite classe représentant un Chien | ||
+ | | ||
+ | */ | ||
+ | public class Chien extends Animal{ | ||
+ | /** | ||
+ | Constructeur de Chien | ||
+ | @param n valeur pour nom | ||
+ | */ | ||
+ | public Chien(String n){ | ||
+ | super(n," | ||
+ | } | ||
+ | /** | ||
+ | Pour faire jouer le chient. | ||
+ | Affiche un petit message en console. | ||
+ | @param a l' | ||
+ | @return true si l' | ||
+ | */ | ||
+ | public boolean jouer(Animal a){ | ||
+ | System.out.println(" | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java Chat.java> | ||
+ | /** | ||
+ | Une toute petite classe représentant un Chat | ||
+ | | ||
+ | */ | ||
+ | public class Chat extends Animal{ | ||
+ | /** | ||
+ | Constructeur de Chat | ||
+ | @param n valeur pour nom | ||
+ | */ | ||
+ | public Chat(String n){ | ||
+ | super(n," | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | Pour faire jouer le chat. | ||
+ | Affiche un petit message en console. | ||
+ | @param a l' | ||
+ | @return true si l' | ||
+ | */ | ||
+ | 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; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Notez au passage l' | ||
+ | |||
+ | La méthode // | ||
+ | |||
+ | La méthode // | ||
+ | |||
+ | Pour plus d' | ||
+ | |||
+ | <code java Souris.java> | ||
+ | /** | ||
+ | Une toute petite classe représentant une Souris | ||
+ | | ||
+ | */ | ||
+ | public class Souris extends Animal{ | ||
+ | /** | ||
+ | Constructeur de Souris | ||
+ | @param n valeur pour nom | ||
+ | */ | ||
+ | public Souris(String n){ | ||
+ | super(n," | ||
+ | } | ||
+ | /** | ||
+ | Pour faire jouer la souris. | ||
+ | Affiche un petit message en console. | ||
+ | @param a l' | ||
+ | @return true si l' | ||
+ | */ | ||
+ | public boolean jouer(Animal a){ | ||
+ | boolean ret = false; | ||
+ | String message = "Je ne joue pas avec les instances de " + a.getClass().getName() ; | ||
+ | if(a instanceof Souris){ | ||
+ | ret=true; | ||
+ | message = "Je joue qu' | ||
+ | } | ||
+ | System.out.println(message); | ||
+ | return ret; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | <code java TestAbstract.java> | ||
+ | /** | ||
+ | | ||
+ | | ||
+ | */ | ||
+ | public class TestAbstract{ | ||
+ | |||
+ | /** | ||
+ | Méthode principale de test | ||
+ | */ | ||
+ | public static void main(String [] trucs){ | ||
+ | //test des | ||
+ | Animal dog1 = new Chien(" | ||
+ | Chien dog2 = new Chien(" | ||
+ | |||
+ | Chat cat1 = new Chat(" | ||
+ | Animal cat2 = new Chat(" | ||
+ | |||
+ | Souris mouse1 = new Souris(" | ||
+ | Animal mouse2 = new Souris(" | ||
+ | |||
+ | //Animal horse1 = new Animal(" | ||
+ | |||
+ | /* | ||
+ | Tests du comportment jouer | ||
+ | */ | ||
+ | |||
+ | boolean d1 = dog1.jouer(dog2); | ||
+ | boolean d2 = dog1.jouer(cat1); | ||
+ | boolean d3 = dog1.jouer(mouse1); | ||
+ | |||
+ | boolean c1 = cat1.jouer(dog2); | ||
+ | boolean c2 = cat1.jouer(cat2); | ||
+ | boolean c3 = cat1.jouer(mouse1); | ||
+ | |||
+ | boolean s1 = mouse1.jouer(dog2); | ||
+ | boolean s2 = mouse1.jouer(cat2); | ||
+ | boolean s3 = mouse1.jouer(mouse2); | ||
+ | |||
+ | System.out.println(" | ||
+ | System.out.println(" | ||
+ | System.out.println(" | ||
+ | |||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | L' | ||
+ | |||
+ | <code bash> | ||
+ | Je joue avec tout le monde moi! | ||
+ | Je joue avec tout le monde moi! | ||
+ | Je joue avec tout le monde moi! | ||
+ | Je ne joue pas avec les chiens, moi! | ||
+ | Je veux bien jouer avec les instances de Chat | ||
+ | Je veux bien jouer avec les instances de Souris | ||
+ | Je ne joue pas avec les instances de Chien | ||
+ | Je ne joue pas avec les instances de Chat | ||
+ | Je joue qu' | ||
+ | Résultat pour dog1:true; true; true | ||
+ | Résultat pour cat1:false; true; true | ||
+ | Résultat pour mouse1: | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== 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' | ||
+ | |||
+ | Les chats sont paresseux, supposons que la classe Chats ne redéfinisse pas la méthode jouer. | ||
+ | |||
+ | Que va dire le compilateur? | ||
+ | |||
+ | <code java> | ||
+ | /** | ||
+ | Pour faire jouer le chat. | ||
+ | Affiche un petit message en console. | ||
+ | @param a l' | ||
+ | @return true si l' | ||
+ | */ | ||
+ | /* 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; | ||
+ | } | ||
+ | */ | ||
+ | </ | ||
+ | |||
+ | Recompilons: | ||
+ | |||
+ | <code bash> | ||
+ | ./ | ||
+ | public class Chat extends Animal{ | ||
+ | </ | ||
+ | |||
+ | Apparemment, | ||
+ | |||
+ | > "Chat n'est pas abstract" | ||
+ | |||
+ | > "...et ne redéfinit pas la méthode abstraite jouer(Animal)" | ||
+ | |||
+ | Quel problème cela pose-t-il pour le compilateur: | ||
+ | |||
+ | 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 // | ||
+ | |||
+ | Il n'y aurait pas de code défini -> le programme ne saurait pas quoi faire. | ||
+ | |||
+ | Le " | ||
+ | |||
+ | Donc, si ce comportement n'est pas définit dans un héritier d' | ||
+ | |||
+ | Le compilateur propose donc deux solutions: | ||
+ | - soit passer la classe Chat en classe abstraite, afin d' | ||
+ | - soit redéfinir la méthode //jouer// dans Chat, pour permettre la construction d' | ||
+ | |||
+ | 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 // | ||
+ | |||
+ | ===== Pour aller encore plus loin: les classes virtuelles pures (ou interfaces en java) ===== | ||
+ | |||
+ | -> ce dernier point fait l' | ||
java/abstract.1383831799.txt.gz · Dernière modification : 2013/11/07 13:43 de bruno