Vous êtes sur la page 1sur 12

Programmation objet

Cas Les animaux étape 1

Pré-requis :
 Programmation objet de base (classe, objet, méthodes) en Java avec Visual Studio Code (VSCode)

T A B L E D E S M A T I E R E S

1. Contexte et objectifs______________________________________________________________1
2. Réalisation______________________________________________________________________2
2.1 Créer la classe Chat_____________________________________________________________________2
2.2 Créer des chats (des objets) et les afficher__________________________________________________2
2.3 Envoyer un message à un objet___________________________________________________________3
2.4 Référence d'objet, type référence_________________________________________________________4
2.4.1 Distinguer type valeur et type référence_________________________________________________________4
2.4.2 Comparaison d'objets de de la classe String______________________________________________________8
2.5 Mettre en oeuvre des méthodes surchargées_______________________________________________9
2.6 Mettre en oeuvre des membres statiques__________________________________________________11
2.7 Créer un tableau d'objets et l'utiliser______________________________________________________12

1. Contexte et objectifs

Représenter des animaux sous la forme de classes d'objets peut être utile dans le cadre de la gestion d'un refuge
d'animaux, d'un zoo, d'un cabinet de vétérinaires, etc..
Le cas Les animaux est ici essentiellement mis en oeuvre à des fins pédagogiques et servira de base à
l'introduction d'un certain nombre de concepts de la programmation objet.

Dans cette première étape, nous allons :


1. Représenter les chats avec une classe,
2. Créer des chats (des objets) et les afficher,
3. Envoyer un message à un objet,
4. Etudier la notion de référence d’objet et distinguer les types valeur et les types référence
5. Mettre en oeuvre des méthodes surchargées
6. Mettre en oeuvre des membres statiques
7. Créer et utiliser un tableau d'objets

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 1/12


2. Réalisation

2.1 Créer la classe Chat


1. Dans votre environnement TP Java, créez un nouveau dossier nommé lesAnimaux1

2. Dans ce dossier lesAnimaux1, créez un fichier nommé Chat.java et implémentez-y la classe Chat selon le
diagramme de classe et les indications ci-dessous :

Chat
- String nom Légende :
- String race
- LocalDate dateNaissance - private
+ String getNom() + public
+ String getRace()
+ int getAge()
+ Chat(String pNom, String pRace, LocalDate pDateNaissance)
+ String decrire()

Une classe est un type abstrait de données muni d’une implémentation éventuellement partielle.

Un constructeur est une méthode qui définit les actions associées à la création d'un objet.

 Le constructeur valorise les champs (attributs ) privés


 La méthode "decrire" permet d'obtenir la chaine ci-dessous en remplaçant les termes en italiques par les
valeurs indiquées :
o nom_du_chat chat de age_du_chat ans de race race_du_chat
 Les accesseurs en lecture (getters) et en écriture (setters) peuvent être générés. Avec VSCode il faut avoir
installé l'extension "Getter and Setter Generator". Sélectionnez les champs, ctrl+maj+P (ou menu
Affichage>Palette de commandes), tapez "gen" et sélectionnez "Generate get and set methods". Les setters
inutiles peuvent bien sûr être supprimés.

 L'accesseur "getAge" est fourni ci-dessous.

    public int getAge()
    {
        LocalDate aujourdhui = LocalDate.now();
        return Period.between(dateNaissance, aujourdhui).getYears();
    }

2.2 Créer des chats (des objets) et les afficher

Nous allons représenter 3 chats et donc créer 3 objets de la classe Chat. L'opération de création d'un objet à partir
d'une classe se nomme l'instanciation. Le résultat de l'instanciation est une instance de classe, en d'autres termes
un objet.

L’instanciation est l’opération de création d’un objet à partir de la classe.


Un objet est une instance de classe.

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 2/12


Dans le programme principal de l'application :

1. créez 3 objets de la classe Chat, vous nommerez les objets felix, sylvestre et isidore. Vous utiliserez les
valeurs affichées ci-dessous dans l'exemple
2. affichez les chats

Exemple d'affichage :

2.3 Envoyer un message à un objet

Pour afficher la description du chat Félix dans la fenêtre Console nous avons écrit :
 System.out.println(felix.decrire());

felix.decrire() est une demande de service envoyée à l'objet felix. On lui demande de nous transmettre sa
description sous la forme d'une chaine de caractères (String). Cette demande de service envoyée à l'objet felix se
nomme un message.

La méthode decrire connaît donc toujours l’objet sur lequel elle agit, c’est l’objet récepteur du message. Il est
inutile de le passer en paramètre, cet objet précède le point .

Dans le message felix.decrire() l'objet qui reçoit le message est felix. Dans l’implémentation de la méthode
decrire, felix (l’objet qui a reçu le message) est appelé alors objet courant et est désigné par this.
(this peut être assimilé à moi)

Exemple
Envoi de message

System.out.println(felix.decrire());

Lors de l’exécution de la méthode decrire de la classe Chat


public String decrire()
{
    //  this désigne l’objet courant, celui qui a reçu le message, dans notre exemple,
    // c’est l’objet felix
    return String.format("%s chat de %d ans de race %s", this.nom, this.getAge(), this.race);
}

//  this étant implicite, l'écriture ci-dessous est équivalente


public String decrire()
{
    return String.format("%s chat de %d ans de race %s", nom, getAge(), race);
}

Un message est une demande de service envoyée à un objet.


Il est assimilé à un appel d’action nommée de la forme :
Message = objet.méthode

Lors de l'appel de unObjet.nomMethode, dans le code de la méthode nomMethode, this désigne


l'objet unObjet, celui qui a reçu le message, celui sur lequel la méthode agit et qui est désigné par
objet courant.

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 3/12


2.4 Référence d'objet, type référence

2.4.1 Distinguer type valeur et type référence

Type valeur

Ajoutez les instructions suivantes dans votre code :

        // type valeur
        int nb;
        nb = 15;
        System.out.printf("\nentier (type valeur) : nb = %d", nb);
        int nbDeux = nb;

Mettez un point d'arrêt (breakpoint) à la ligne 21 comme suit. Il suffit de cliquer à gauche du numéro de
ligne :

Exécutez les instructions en mode débogage pour faire apparaitre les informations détaillées :

 L'instruction surlignée de jaune n'est pas encore exécutée. On peut observer le contenu des variables au
fur et à mesure dans le volet de gauche (variables) et en surligné jaune dans le code :

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 4/12


Pour l'instant, la variable nb est seulement déclarée et non assignée.

Cliquez sur l'outil "Pas à pas principal"

la variable nb a comme valeur 15. Ici en mode débogage, VSCode affiche la valeur de la variable.

nb désigne une variable de type valeur. La valeur est directement stockée à l'adresse mémoire indiquée par nb

Cliquez sur l'outil "Pas à pas principal"

Comme nb est une variable de type valeur son affichage affiche sa valeur, ici on affiche simplement la valeur 15.
On obtient :

Cliquez sur l'outil "Pas à pas principal"

la variable nbDeux contient maintenant la même valeur que nb.

Type référence

Ajoutez les instructions suivantes dans votre code :

        // référence d'objet,  type référence
        Chat picasso;
        picasso = new Chat("Picasso", "persan", LocalDate.of(2012, 6, 15));
        System.out.printf("\nobjet crée avec new : picasso = %s", picasso);

        Chat theodore = picasso;

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 5/12


Enlevez le point d'arrêt ligne 21 (en cliquant dessus) et mettez un point d'arrêt (breakpoint) à la ligne 30
comme suit. Il suffit de cliquer à gauche du numéro de ligne :

Exécutez les instructions ci-dessous en mode débogage pour faire apparaitre les informations
détaillées :

picasso désigne la référence de l'objet. L'objet est seulement déclaré et non crée. La référence ne donne
aucune adresse (pointeur null affiché dans un autre EDI :

).
Cliquez sur l'outil "Pas à pas principal"

Après exécution de la ligne 30 (new Chat) la référence d'objet correspond maintenant à une adresse
mémoire. A cette adresse on trouve les valeurs des attributs de l'objet. Ici en mode débogage, VSCode affiche
les valeurs des attributs et des propriétés (accesseurs) dans le volet de gauche.

Cliquez sur l'outil "Pas à pas principal"

Comme picasso est une référence d'objet (une adresse en mémoire) son affichage n'a pas de sens
pour l'utilisateur, ici avec un System.out.printf on affiche simplement le type (la classe) de l'objet (suivi d'une
adresse) et non ses attributs.
On obtient :

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 6/12


Cliquez sur l'outil "Pas à pas principal"

la variable objet theodore contient maintenant la même référence que picasso et désigne donc le même objet.

La référence d'objet correspond à une adresse mémoire. A cette adresse on trouve les valeurs des attributs
de l'objet.

Si on exécute l'instruction : System.out.println(felix);

On obtient par exemple : Chat@606d8acf


Comme felix est une référence d'objet (une adresse en mémoire) son affichage n'a pas de sens pour l'utilisateur.

Exemple graphique avec la classe Chat


unChat i.

null
Chat unChat;

unChat désigne la référence de l'objet. L'objet est


seulement déclaré et non crée. La référence ne donne ??
aucune adresse.

unChat
unChat = new Chat("Félix", "persan",
LocalDate.of(2009, 6, 15)); @606d8acf
@606d8acf
@606d8acf
la référence d'objet correspond maintenant à l'adresse
mémoire (simplifiée). Cette adresse se situe dans le 20090615 Félix persan
segment de mémoire nommé le tas. A cette adresse on
trouve les valeurs des attributs de l'objet.

Chat unMinet = unChat; unChat

la variable objet unMinet contient maintenant la même @606d8acf


référence que unChat et désigne donc le même objet.
@606d8acf

20090615 Félix persan


unMinet
@606d8acf

Type référence

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 7/12


Les objets sont créés dynamiquement (au cours de l'exécution du programme) par instanciation de la classe
(opérateur new). Cette opération alloue dynamiquement de la mémoire dans un segment de mémoire
particulier qu’on nomme le tas. La variable objet est de type référence; elle ne contient pas la valeur des attributs
de l'objet, mais leur adresse (leur référence) en mémoire.

Lorsque l’opérateur new est invoqué en association avec un constructeur il renvoie une référence à l'objet
nouvellement alloué et initialisé du type classe.

La référence de l’objet désigne un objet (une instance d’une classe) qui dispose d'un exemplaire
unique des attributs déclarés dans la classe. Elle correspond à l'adresse de l'objet en mémoire centrale.

Lors de l’instanciation, les méthodes ne sont pas dupliquées.

2.4.2 Comparaison d'objets de de la classe String

1. Ajoutez le code ci-dessous à la fin de la méthode main de la classe App.java.

// ********* particularités classe String
System.out.println("\n\n\n STRING\n");
String salut = "salut";
String salut2 = "salut";
String salut3 = new String("salut");

System.out.printf("\nsalut = %s    salut2 = %s    salut3 = %s\n\n", salut, salut2, salut3);
System.out.printf("\nsalut != salut2 = %s", salut != salut2);       // false
System.out.printf("\nsalut == salut2 = %s", salut == salut2);       // true
System.out.printf("\nsalut.equals(salut2) = %s", salut.equals(salut2));       // true
System.out.printf("\nsalut3 != salut2 = %s", salut3 != salut2);     // true
System.out.printf("\nsalut3 == salut2 = %s", salut3 == salut2);     // false
System.out.printf("\nsalut.equals(salut3) = %s", salut.equals(salut3));       // true
System.out.printf("\nid salut = %d", System.identityHashCode(salut));   // identité objet
System.out.printf("\nid salut2 = %d",System.identityHashCode(salut2));
System.out.printf("\nid salut3 = %d",System.identityHashCode(salut3));

salut2 = "bonjour";
System.out.printf("\n**********\nsalut = %s    salut2 = %s", salut, salut2);
System.out.printf("\nsalut != salut2 = %s", salut != salut2);       // true
System.out.printf("\nsalut == salut2 = %s", salut == salut2);       // false
System.out.printf("\nsalut.equals(salut2) = %s", salut.equals(salut2));       // false
System.out.printf("\nid salut = %d", System.identityHashCode(salut));
System.out.printf("\nid salut2 = %d",System.identityHashCode(salut2));
System.out.printf("\nid salut3 = %d",System.identityHashCode(salut3));

// == compare les références d'objets
// equals compare les valeurs des objets. La méthode equals() permet de tester l'égalité de 
deux objets d'un point de vue sémantique.

2. Exécutez, vous obtenez les résultats des tests comme indiqué dans les commentaires.

3. Notez bien que :

 == compare les références d'objets c’est-à-dire l'identité des objets


 equals() compare les valeurs des objets. La méthode equals() permet de tester l'égali
té de deux objets d'un point de vue sémantique.

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 8/12


4. Commentez les lignes ajoutées dans ce point 2.4 afin qu'elles ne soient plus exécutées.

2.5 Mettre en oeuvre des méthodes surchargées


En général le cri (le miaulement) d'un chat correspond à "Miaou". Certains chats ont un miaulement plus
spécifique et miaulent à plusieurs reprises. Pour représenter ces particularités, une solution consiste à :
1. Conserver le cri de chaque chat en créant un nouvel attribut dans la classe Chat
2. Créer un deuxième constructeur avec en paramètre supplémentaire le cri spécifique de l'animal,
3. Positionner le cri à "Miaou" dans le constructeur qui correspond au cas général
4. Créer une méthode pour faire miauler un chat
5. Créer une autre méthode pour obtenir le miaulement à plusieurs reprises.

5. Conserver le cri de chaque chat en créant un nouvel attribut dans la classe Chat,
Ajoutez l'attribut (le champ) cri dans la classe Chat :

public class Chat {
    // champs, attributs
    private String nom;
Classe Chat
    private String race;
    private LocalDate dateNaissance;
    private String cri;

6. Créer un deuxième constructeur avec en paramètre supplémentaire le cri spécifique de l'animal,


Le nom du constructeur doit obligatoirement correspondre au nom de la classe. Ce deuxième constructeur portera
donc le même nom Chat. Il se distinguera du premier par sa liste de paramètres. Comme le constructeur existe en
plusieurs exemplaires, on dit que le constructeur est surchargé. Le constructeur étant une méthode, il s'agit
aussi de façon plus générale d'une méthode surchargée.

    // constructeur surchargé
//  = redéfini avec le même nom mais une liste de paramètres différente
Créer le     public Chat(String pNom, String pRace, LocalDate pDateNaissance, String pCri) {
constructeur
        nom = pNom;
ci contre
        race = pRace;
(B)         dateNaissance = pDateNaissance;
        cri = pCri;
    }

7. Positionner le cri à "Miaou" dans le constructeur qui correspond au cas général


Ajoutez l'instruction cri = "Miaou"; dans le constructeur de la classe Chat :

    // constructeur surchargé
// = redéfini avec le même nom mais une liste de paramètres différente
constructeur     public Chat(String pNom, String pRace, LocalDate pDateNaissance) {
de la classe
        nom = pNom;
Chat
        race = pRace;
(A)         dateNaissance = pDateNaissance;
        cri = "Miaou";
    }

Le constructeur qui sera exécuté lors de la création d'un objet Chat sera celui qui correspond à la liste de
paramètres à l'appel

Chat felix = new Chat("Félix", "persan", LocalDate.of(2009, 6, 15));
 Le constructeur (A) est exécuté

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 9/12


Chat tigrou = new Chat("Tigrou", "Gouttiére", LocalDate.of(2011, 8, 23), "Miiiou");
 Le constructeur (B) est exécuté

 Ajouter ceci à la suite de votre programme :


// invoquer constructeur surchargé
Chat tigrou = new Chat("Tigrou", "Gouttiére", LocalDate.of(2011, 8, 23), "Miiiou");

Modifiez la méthode decrire pour afficher également le cri.


Affichez également la description de tigrou.
Vous obtenez :
=== MES CHATS ===
Félix chat de 12 ans de race persan. Son cri est Miaou
Sylvestre chat de 11 ans de race gouttiére. Son cri est Miaou
Isidore chat de 14 ans de race siamois. Son cri est Miaou
Tigrou chat de 9 ans de race Gouttiére. Son cri est Miiiou

8. Créer une méthode pour faire miauler un chat.

 Ecrivez la méthode miauler :

    public String miauler() {
        return cri + " !";
    }

9. Créer une autre méthode pour obtenir le miaulement à plusieurs reprises.


Nous pourrions créer une méthode nommée par exemple MiaulerPlusieursFois, mais il y a plus simple pour créer
juste une variante de la méthode Miauler. Il est inutile de chercher un nom distinct et explicite, il suffit d'utiliser le
même nom de méthode Miauler et de distinguer cette autre version par une liste de paramètres différente. Il
s'agit alors d'une méthode surchargée.

 Ecrivez la 2e version de la méthode miauler :

   // méthode surchargée = redéfinie avec le même nom mais une liste de paramètres différente
    public String miauler(int nombre) {
        String uneChaine = "";
        if (nombre > 0) {
            for (int i = 1; i <= nombre; i++) {
                uneChaine += cri + " ";
            }
        }
        return uneChaine;
    }

 Invoquez les deux méthodes pour observer la différence

Dès que vous saisissez le point après le nom d'un objet Chat, Visual Studio Code affiche la liste des possibilités. Les
deux versions de la méthode miauler sont bien présentées :

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 10/12


Ajoutez les instructions suivantes :

        // invoquer méthode surchargée
        System.out.printf("\nAppel felix.miauler() : %s", felix.miauler());
        System.out.printf("\nAppel felix.miauler(5) : %s", felix.miauler(5));
        System.out.printf("\nAppel tigrou.miauler() : %s", tigrou.miauler());
        System.out.printf("\nAppel tigrou.miauler(5) : %s", tigrou.miauler(5));

vous obtenez :

Appel felix.miauler() : Miaou !


Appel felix.miauler(5) : Miaou Miaou Miaou Miaou Miaou
Appel tigrou.miauler() : Miiiou !
Appel tigrou.miauler(5) : Miiiou Miiiou Miiiou Miiiou Miiiou
Appel méthode Chat.Miaulement : Miaou

Définition :

Une méthode redéfinie avec une autre liste d’arguments est appelée une méthode surchargée.

2.6 Mettre en oeuvre des membres statiques

Observons le constructeur
   public Chat(String pNom, String pRace, LocalDate pDateNaissance) {
        nom = pNom;
        race = pRace;
        dateNaissance = pDateNaissance;
        cri = "Miaou";
    }

On constate qu'un littéral "Miaou" y est utilisé. En fait il s'agit du cri par défaut pour un chat. C'est une sorte de
constante. Le "Miaou" n'est pas propre à un chat en particulier, mais à tous les chats, c'est-à-dire à la notion même
de chat. Ainsi, il serait préférable de définir le "Miaou" comme tel, c'est-à-dire comme un attribut de la classe Chat.
C'est possible en le définissant comme un attribut statique. Comme les autres classes ne sont pas autorisées à
accéder à ce champ, nous allons le protéger en le déclarant comme un membre privé de la classe Chat ( private).

 Ajouter l'attribut statique dans la classe Chat :

    // champ statique (à portée classe et non instance)
    private static String Miaulement = "Miaou";

 Utilisez cet attribut statique dans le constructeur Chat

   // constructeur surchargé = redéfini avec le même nom mais une liste de paramètres différente
    public Chat(String pNom, String pRace, LocalDate pDateNaissance) {
        nom = pNom;
        race = pRace;
        dateNaissance = pDateNaissance;
        cri = Chat.Miaulement;
    }

Remarques :
La déclaration d’un membre statique est précédée du mot réservé : static.
Comme un membre statique a une portée classe et non instance, son invocation prend la forme :
BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 11/12
nom_classe.nom_membre_statique

Un membre statique d’une classe est invoqué sans création préalable d’un objet de la classe.

Un membre statique est un membre à portée classe.

 Autorisez l'accès en lecture aux autres classes

L'attribut statique miaulement est privé et ne peut donc être utilisé que dans le corps de la classe Chat. Afin de
permettre l'accès en lecture aux autres classes, nous allons créer un accesseur en lecture .

    // méthode statique  (à portée classe et non instance)
    public static String getMiaulement() {
        return Chat.Miaulement;
    }

 Appelez cet accesseur (un accesseur est également une méthode) dans le programme

// invoquer accesseur statique
System.out.printf("\nAppel méthode Chat.getMiaulement : %s\n", Chat.getMiaulement());

 Observez que les membres statiques ne sont pas proposés pour un objet (une instance de classe) :

 Observez que les membres d'instance ne sont pas proposés pour la classe :

2.7 Créer un tableau d'objets et l'utiliser

1. Dans le programme, déclarer un tableau de 3 chats et remplissez le tableau avec les 3 chats crées
précédemment.
2. Afficher la description de chaque chat en parcourant le tableau avec un for
3. Afficher le nombre de chats en utilisant le nombre d'éléments du tableau
4. Afficher la description de chaque chat en parcourant le tableau avec un foreach
5. Parcourir le tableau pour calculer et afficher la moyenne d'âge des chats
6. Parcourir le tableau pour chercher le chat le plus jeune et afficher son nom et son âge.

BLOC2 Programmation objet : cas lesAnimaux1 Marianne Delio page 12/12

Vous aimerez peut-être aussi