Introduction à la programmation orientée objet 1 - Version 2018/2019 - Java CNPI

La page est créée Delphine Masse
 
CONTINUER À LIRE
Introduction à la programmation orientée objet 1 - Version 2018/2019 - Java CNPI
Introduction à la
 programmation
orientée objet 1

    Version 2018/2019
CNPI-Gdt-PrograTG'17                         Introduction à la programmation orientée objet                                    3GIG

Table des matières
1. Notions importantes...............................................................................................7
   1.1. Qu'est-ce qu'un « objet » ?..................................................................................7
   1.2. Exemples d'introduction.......................................................................................8
       1.2.1. Exemple 1 : Voitures................................................................................................8
       1.2.2. Exemple 2 : Personnes..............................................................................................9
   1.3. Qu'est-ce qu'une « classe » ?.............................................................................10
   1.4. Qu'est-ce qu'un « attribut » ?.............................................................................12
   1.5. Qu'est-ce qu'une « méthode » ?..........................................................................13
       1.5.1. L'instruction return.................................................................................................14
       1.5.2. Le type void...........................................................................................................14
   1.6. Qu'est-ce qu'un « paramètre » ?.........................................................................17
   1.7. Qu'est-ce qu'un « type » ?.................................................................................20
   1.8. Conventions de noms pour les méthodes.............................................................22
       1.8.1. Les accesseurs - préfixe get.....................................................................................22
       1.8.2. Les manipulateurs - préfixe set.................................................................................22
       1.8.3. Les méthodes effectuant un calcul - préfixe calculate...................................................22
       1.8.4. Les méthodes booléennes - préfixes is/has.................................................................22
       1.8.5. La méthode toString...............................................................................................22
   1.9. Qu'est-ce qu'un « constructeur » ?......................................................................23
   1.10. Qu'est-ce qu'une « variable » ?.........................................................................24
   1.11. Opérateurs, compatibilité et conversions............................................................26
       1.11.1. Opérateur d'affectation « = ».................................................................................26
       1.11.2. Opérateurs arithmétiques......................................................................................26
       1.11.3. Conversions forcées de types (explicites).................................................................27
       1.11.4. Conversions automatiques de types (implicites)........................................................27
       1.11.5. Opérateur de concaténation « + »...........................................................................29
   1.12. Affichage d'une ligne de texte...........................................................................29
   1.13. La classe « Math »...........................................................................................30
   1.14. Générer des nombres aléatoires........................................................................31
2. Présentation et documentation du code...............................................................33
   2.1. Qu'est-ce qu'un « commentaire » ?.....................................................................33
       2.1.1. Règles pour l'utilisation des commentaires «JavaDoc»..................................................33
       2.1.2. Précisions : les commentaires « JavaDoc » des classes................................................34
       2.1.3. Précisions : les commentaires « JavaDoc » des méthodes.............................................34
   2.2. Qu'est-ce que « l'indentation » ?.........................................................................35
3. Les structures de contrôle....................................................................................36
   3.1. La structure alternative......................................................................................36
   3.2. La structure alternative et le retour de résultats....................................................38
   3.3. Les opérateurs de comparaison...........................................................................39
   3.4. Les opérateurs logiques.....................................................................................40
   3.5. La structure répétitive « tant que ».....................................................................41

[ver. 26 sept. 2018]                                     Page 2 de 47
3GIG              Introduction à la programmation orientée objet                         CNPI-Gdt-PrograTG'17

   3.6. La structure répétitive « pour »...........................................................................43
   3.7. Les blocs et la durée de vie des variables.............................................................45
4. Annexe : Automatisation des tests des classes....................................................46
   4.1. Création d'objets avec «new».............................................................................46
   4.2. Saisie de données au clavier en mode texte.........................................................46
   4.3. Démarrage automatique du programme...............................................................47

                                                  Page 3 de 47                                     [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17              Introduction à la programmation orientée objet        3GIG

Sources
     •    Introduction à Java, Robert Fisch, 2009
     •    Introduction à la programmation, Robert Fisch, 11TG/T0IF, 2006
     •    Introduction à la programmation, Simone Beissel, T0IF, 2003
     •    Programmation en Delphi, Fred Faber, 12GE/T2IF, 1999
     •    Programmation en Delphi, Fred Faber, 13GI/T3IF, 2006
     •    Programmation en ANSI-C, Fred Faber, T3IF, 1993-2006

Adaptations et actualisations
         Fred Faber

Contributeurs
         Gilles Everling, Guy Rhein, Claude Sibenaler

Site de référence
         http://java.cnpi.lu

A la base de ce cours est le document « Introduction à Java » de Robert Fisch.
Le cours est adapté et complété en permanence d'après les contributions des enseignants.
Les enseignants sont priés d'envoyer leurs remarques et propositions via Mail à Fred Faber ou
Robert Fisch qui s'efforceront de les intégrer dans le cours dès que possible.
La version la plus actuelle est publiée sur le site : http://java.cnpi.lu
Des ressources supplémentaires pour enseignants sont publiés sur l'espace de travail
Informatique de eduDocs.

[ver. 26 sept. 2018]                       Page 4 de 47
3GIG           Introduction à la programmation orientée objet             CNPI-Gdt-PrograTG'17

Introduction
Ce cours d'introduction à la programmation suit le principe "objects first" - "les objets
d'abord" et ceci dans un double sens :
   •   au centre des intérêts se trouve la programmation orientée objet : tous les exemples
       ou exercices sont traités du point de vue orienté objet,
   •   le cours commence par l'introduction des principes et du vocabulaire orienté objet avant
       même de traiter les opérateurs et les structures de programmation.

Dans le cours de 3e, nous allons développer des classes et manipuler des objets, sans pour
autant nous occuper de l'interface ni de la saisie ou de la représentation des données.
Le logiciel Unimozer joue le rôle de "banc d'essai" pour nos objets et nous permet de vérifier le
bon fonctionnement de nos classes sans que nous n'ayons besoin de développer des
applications autour de nos classes. Ainsi Unimozer crée automatiquement des dialogues pour
demander les valeurs et pour afficher des résultats.
Exemple : Le projet 'Cistern' en 3e

Lors du test de la méthode add, c'est Unimozer qui crée automatiquement un dialogue pour
nous demander le nombre de litres à ajouter à la citerne.

Dans le cours de 2e, nous allons voir comment
développer des applications avec des interfaces
graphiques individuels pour visualiser et manipuler nos
objets.
Exemple : Le projet 'Cistern' en 2e
Ce programme utilise la classe Cistern que nous avons
développée en 3e, mais en 2e nous saurons construire
une interface plus conviviale pour présenter et changer
le contenu de la citerne. Ainsi, les détails de la
réalisation resteront cachés à l'utilisateur.

                                         Page 5 de 47                             [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17               Introduction à la programmation orientée objet          3GIG

Conventions :
Dans ce cours, nous allons utiliser des désignations anglaises pour tous les éléments que nous
définissons dans le code de nos classes (noms des classes, attributs, méthodes, variables, ...).
Ainsi, nous évitons :
     •    d'une part des aberrations linguistiques (p.ex: getValeur, setMoyenne),
     •    d'autre part des incompatibilités dues par exemple à des caractères accentués.
De préférence, les textes retournés par nos objets ou affichés à l'écran seront des textes
anglais. Les commentaires dans notre code seront de préférence en français et serviront donc
aussi à expliciter les désignations anglaises moins connues.

[ver. 26 sept. 2018]                       Page 6 de 47
3GIG           Introduction à la programmation orientée objet           CNPI-Gdt-PrograTG'17

1.     Notions importantes
OOP - Object Oriented Programming - objektorientierte Programmierung
POO - Programmation orientée objet
Dans la programmation Java, nous allons manipuler des « objets » dont les « attributs » et les
« méthodes » sont définis dans des « classes ». Dans ce chapitre, nous allons essayer
d'éclaircir ce vocabulaire qui constitue le fondement de la programmation orientée objet.

1.1.    Qu'est-ce qu'un « objet » ?
Dans la vie courante, toute chose, vivante ou non, peut être appelée objet. Les « objets »
peuvent être une montre, un thermomètre, un client, un rendez-vous par exemple.
Nous pouvons définir un objet informatique comme suit :

Un objet est la représentation informatique d'un individu, d'un objet ou d'un concept de la vie
réelle. Il est défini par ses caractéristiques propres (appelés « champs » ou « attributs ») et
par son comportement (ses « méthodes »).

Cependant, chaque individu décrit un même objet différemment parce que chaque observateur
a une autre personnalité, d'autres préférences, d'autres priorités, un autre point de vue.
Ainsi, chacun attribue d'autres importances aux caractéristiques d'un objet. On dit que chaque
personne a une perception différente de la même chose. L'homme crée donc une image
abstraite d'un objet dans sa tête. On dit qu'on a fait abstraction.

L'abstraction est le fait d'ignorer les propriétés marginales et de se concentrer sur les
aspects essentiels. C'est un principe essentiel pour pouvoir gérer la complexité du monde réel
dans le domaine informatique.

En informatique, l'abstraction nous permet de ne considérer que les caractéristiques les plus
importantes des objets que nous manipulons.

                                        Page 7 de 47                             [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17               Introduction à la programmation orientée objet           3GIG

1.2.        Exemples d'introduction
Avant de passer aux définitions plus formelles du vocabulaire de la POO, discutons quelques
exemples pour comprendre l'approche de la modélisation d'objets dans la programmation.

1.2.1.        Exemple 1 : Voitures
Trois personnes, Monsieur X, Madame Y et Monsieur Z, possèdent chacun leur propre voiture.
Chacune de leurs voitures a 4 roues, un moteur, une certaine vitesse de pointe et ainsi de
suite. De même, chacune de ces voitures peut accélérer, freiner, changer de direction, etc. On
voit donc que chacune de ces trois voitures a le même type d'attributs et de
comportements ou fonctionnalités. C'est pour cela qu'on dit que ce sont des voitures.
Et pourtant, les trois voitures ne sont pas identiques. En fait, voici une comparaison des trois
voitures :

Propriétaire                      Monsieur X          Madame Y            Monsieur Z

Peinture                          verte               blanche             noire

Poids                             1.500 kg            1.200 kg            1.700 kg

Puissance                         100 kW              75 kW               170 kW

Vitesse de pointe                 190 km/h            180 km/h            254 km/h

Accélérer                         oui                 oui                 oui

Freiner                           oui                 oui                 oui

Changer de direction              oui                 oui                 oui

Nous pouvons dire que les 3 véhicules partagent les mêmes types de caractéristiques d'un
point de vue conceptionnel :

     •    chaque véhicule a un propriétaire, une certaine peinture, un certain poids, une certaine
          puissance et une certaine vitesse de pointe (→ attributs)

     •    chaque véhicule peut accélérer, freiner et changer de direction (→ méthodes).

Il y a bien sûr de nombreuses autres caractéristiques que nous allons ignorer dans cet
exemple, afin de limiter la complexité (→ abstraction).

Même si les valeurs des attributs sont individuelles, les trois objets sont quand même des
objets similaires qui ont la même identité : ce sont des voitures (et non pas des téléphones,
des chaises ou des pommes).
On peut donc dire qu'il s'agit de trois objets différents, qui appartiennent tous à la même
classe, appelée « Voiture ».
En d'autres mots, la classe décrit le type d'objet.
Un objet concret et spécifique est appelé une instance (une réalisation) d'une classe.
Ainsi l'objet « voiture de Monsieur X » est une instance de la classe « Voiture ». Il en est de
même pour les deux autres voitures.

[ver. 26 sept. 2018]                         Page 8 de 47
3GIG            Introduction à la programmation orientée objet             CNPI-Gdt-PrograTG'17

1.2.2.    Exemple 2 : Personnes
Dans votre salle de classe, il y a un nombre d'individus, d'« objets vivants ».
   •   Chacun de ces objets a 2 bras, 2 jambes, une tête, une personnalité, un certain âge, un
       lieu de résidence, etc.
   •   De même, chacun de ces objets peut marcher, s'asseoir, courir, rire, parler, etc.
Il y a toute une série de types d'attributs et de comportements ou de méthodes que ces
objets ont en commun. On peut donc qualifier tous les objets vivants dans cette salle d'êtres
humains. On dit que ces objets sont des instances de la classe « être humain ».
On remarque à nouveau que chacun de ces objets se distingue des autres. Ainsi nous avons
tous les mêmes types d'attributs et de méthodes, mais nos attributs n'ont pas toujours la
même valeur. P. ex. certains ont des cheveux bruns, d'autres des cheveux noirs, d'autres des
cheveux blonds. Nous avons des tailles et personnalités différentes, etc. Nous sommes donc
tous des objets différents, mais nous faisons partie de la même classe.

       Reprenons maintenant le vocabulaire de façon plus formelle et
                     intéressons-nous à la pratique de la POO...

                                          Page 9 de 47                            [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17                 Introduction à la programmation orientée objet              3GIG

1.3.        Qu'est-ce qu'une « classe » ?

Une classe est une description formelle d'une collection d'objets similaires, de même identité.

Prenons l'exemple d'une classe dénommée Ball.
En UML (Unified Modeling Language), la classe est représentée par un diagramme de
classe :

Le code source y relatif est le suivant :
 public class Ball
 {
 }

Explications :
     ●    Le mot clé « public » indique qu'il s'agit d'une classe publique, c'est-à-dire d'une
          classe qui est utilisable par d'autres programmes ou d'autres classes.
     ●    Le mot clé « class » indique qu'il s'agit d'une classe.
     ●    Le mot «Ball» est le nom de cette classe. Par convention la première lettre d'un nom
          de classe en Java est écrite en majuscules et le reste en minuscules. Des caractères
          spéciaux ne sont pas admis !
     ●    Les accolades « { » et « } » indiquent le début, respectivement la fin de la classe.
Comme défini précédemment, une classe est une description formelle d'une collection d'objets
de même identité. Il s'agit donc purement d'une description générale. Un objet est une
instance d'une classe, c'est-à-dire que l'objet est créé dans la mémoire de
l'ordinateur en suivant exactement les définitions contenues dans la classe. Tous les
objets instanciés à partir d'une même classe possèdent le même fonctionnement.
Autre analogie pour clarifier ces deux vocables :
         classe         correspond     au plan d'une maison
         objet          correspond     à la maison construite selon le plan
En POO, nous allons donc définir d'abord une ou plusieurs classes. Lorsque nous voulons tester
ou faire tourner un programme, nous devons créer une ou plusieurs instances de ces classes.
Ce sont ces instances qui 'vivent' dans la mémoire de l'ordinateur et avec lesquelles nous
pouvons interagir.
Comme désignations pour nos classes et objets, nous allons utiliser des noms ou des noms
composés, p.ex. :
         classes :      Person,        Client,       TennisBall,          SavingsAccount
         objets :       person1,       client,       laurasTennisBall,    savingsAccount

En programmation, on dit qu'un objet est une « instance » d'une classe.
Le fait de créer un objet à partir d'une classe donnée s'appelle « instanciation ».

[ver. 26 sept. 2018]                         Page 10 de 47
3GIG           Introduction à la programmation orientée objet             CNPI-Gdt-PrograTG'17

Reprenons l'exemple de la classe Ball :

Ball est la classe et contient la description abstraite (le plan) d'une balle dans le contexte de
notre programme.
larasTennisBall, mikesBasketBall et bobsVolleyBall sont des instances de la classe
Ball, donc des objets, c.-à-d. des balles concrètes avec leurs caractéristiques spécifiques
(avec des valeurs différentes pour leur taille, leur couleur, leur pression).

L'environnement de développement (Unimozer)
Dans ce cours, nous utilisons un environnement de développement très simple (Unimozer) qui
nous permet de construire des classes, de créer des instances, de voir leur contenu et de les
tester.
Unimozer par exemple, affiche automatiquement la représentation UML correcte de la classe
dans la partie gauche de l'écran. Le code Java se trouve dans la fenêtre à droite. L'outil
actualise les données dans deux directions, c.-à-d. lorsque nous modifions le code Java, la
représentation UML est actualisée automatiquement et vice-versa.

Exercice résolu :
   •   Si vous ne l'avez pas encore fait, alors créez un dossier pour vos exercices Java. Ouvrez
       votre interface de développement et ajoutez la classe publique Ball. Sauvez le projet
       sous '00_Exercice_resolu' dans votre dossier Java.
   •   Compilez la classe.
   •   Créez une nouvelle instance du nom de larasTennisBall de la classe Ball.
   •   Créez ensuite des        nouvelles   instances     du   nom   de   mikesBasketBall          et
       bobsVolleyBall.

                                          Page 11 de 47                           [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17                    Introduction à la programmation orientée objet       3GIG

1.4.          Qu'est-ce qu'un « attribut » ?
Un « champ » (angl. : field) ou « attribut » d'une classe est une propriété qu'elle possède.
Voici quelques exemples courants :
     •    La couleur d'une voiture est une propriété.
     •    La puissance dissipée d'une ampoule électrique est une propriété.
     •    La nationalité, âge et la taille sont des propriétés d'une personne.
     •    Le diamètre, le poids, la pression, la couleur sont les propriétés d'une balle.

Chaque attribut possède un certain type (→ voir chapitre 1.7) et un certain nom.
En UML, un attribut est inscrit dans la deuxième case d'un diagramme de classe. Voici un
exemple de la classe Ball qui possède un attribut radius du type double (nombre réel) :

Le code source y relatif est le suivant :
public class Ball
{
     private double radius = 0;
}

Explications :
     ●    Les attributs d'une classe doivent être protégés afin qu'uniquement les méthodes de la
          classe elle-même y aient accès. C'est pour cette raison que toutes les déclarations
          d'attributs que nous utilisons commencent par le mot clé « private ».
     ●    L'attribut représente ici un nombre réel, donc du type double (→ voir chapitre 1.7).
     ●    radius est le nom de l'attribut.
          Par convention les noms des attributs en Java sont écrits en lettres minuscules. Si le
          nom se compose de plusieurs mots, la première lettre de chaque mot est écrite en
          majuscules, sauf pour le premier mot (p.ex. numberOfSides ).
     ●    L'attribut radius est initialisé dès sa déclaration par la valeur zéro.
          Une déclaration d'un attribut sans initialisation se lirait comme suit :
          private double radius;

Exercice résolu :
Ajoutez l'attribut pressure du type double à la classe Ball. Cet attribut contient la pression
de la balle. Initialisez-le par la valeur 2,50. Compilez la classe et créez quelques objets. Que
remarquez-vous lorsque vous inspectez les objets ?
     •    Étapes à suivre dans Unimozer :
          ◦    clic droit sur l'objet
          ◦    Add field …
          ◦    puis entrez le nom et le type de l'attribut

[ver. 26 sept. 2018]                           Page 12 de 47
3GIG             Introduction à la programmation orientée objet           CNPI-Gdt-PrograTG'17

1.5.      Qu'est-ce qu'une « méthode » ?
Une méthode est un sous-programme qui décrit une action que les instances de la classe
savent effectuer. En termes informatiques, une méthode n'est rien d'autre qu'une suite
d'instructions qui sont exécutées lorsqu'on fait appel à la méthode.
Une méthode peut retourner une valeur comme résultat ou ne rien retourner du tout ( → voir
chapitre 1.5.2 ).
Le plus souvent, les méthodes changent le contenu des attributs de la classe ou utilisent les
attributs de la classe pour effectuer une opération.

Exemple :
Donnons aux balles la capacité de nous fournir la valeur de leur diamètre :

En UML, une méthode est inscrite dans la troisième case d'un diagramme de classe :
En Java le code source y relatif est le suivant :
public class Ball
{
     private double radius = 11.95;
                                                       calculateDiameter est une méthode
        public double calculateDiameter()                   publique qui retourne une
        {                                                valeur décimale (du type double)
             return 2 * radius;
        }
}

Explications :
    ●    Le code source d'une méthode est indenté d'une tabulation par rapport au corps de la
         classe (→ voir chapitre 2.2).
    ●    Le mot clé « public » indique qu'il s'agit d'une méthode publique, c'est-à-dire d'une
         méthode qui est utilisable par d'autres sous-programmes ou d'autres classes.
    ●    Le mot clé « double » indique que la méthode retourne un nombre décimal (→ détails
         voir chapitre 1.7). En UML, le type du résultat est noté derrière le nom de la méthode
         (séparé par un « : »).      Dans notre exemple: calculateDiameter() : double
    ●    Le mot « calculateDiameter » est le nom de cette méthode.
         Les noms des méthodes en Java sont écrits en lettres minuscules. Si le nom se
         compose de plusieurs mots, la première lettre de chaque mot est écrite en majuscules,
         sauf pour le premier mot. Les noms des méthodes contiennent toujours un verbe.
    ●    Les accolades « { » et « } » indiquent le début, respectivement la fin de la méthode.
    ●    Une méthode peut avoir besoin de paramètres (→ voir chapitre 1.6) qui sont alors
         indiqués entre parenthèses derrière le nom de la méthode. Dans notre cas, la méthode
         ne possède pas de paramètres. Nous devons indiquer ce fait par une paire de
         parenthèses vide () derrière le nom.

                                          Page 13 de 47                            [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17             Introduction à la programmation orientée objet              3GIG

1.5.1.        L'instruction return
Une méthode qui ne travaille pas seulement avec les attributs, mais qui retourne en plus un
résultat doit contenir l'instruction return. Le type du résultat à fournir doit être noté devant le
nom de la méthode. L'instruction return se trouve en général à la fin de la méthode.
L'instruction return sert à :
     1. retourner comme résultat de la méthode la valeur (ou le résultat de l'expression) qui
        se trouve derrière le mot clé return. Cette valeur ou expression doit nécessairement
        avoir le même type que la méthode.
     2. quitter immédiatement la méthode.

1.5.2.        Le type void
Le type void (DE: leer / FR: vide) est un type spécial qui est uniquement utilisé lors de la
déclaration de méthodes. Une méthode retourne le type void si elle effectue un travail sans
pour autant retourner un résultat. Evidemment, une telle méthode ne possède pas
d'instruction return.

Remarque :
Une méthode qui n'est pas du type void doit dans tous les cas se terminer par une
instruction return. Si on oublie une instruction return, le compilateur s'arrête avec le
message d'erreur 'missing return statement'. Ceci jouera un rôle plus important lors du
traitement des structures alternatives et répétitives (→ voir chapitre 3.1).

Exemple :
La classe suivante permet de calculer la circonférence de la balle et d'afficher ses informations:
public class Ball
{                                           calculateCircumference est une méthode publique
  private double radius = 23.9;                      (sans paramètres) qui retourne
                                                    une valeur décimale (type double)
    public double calculateCircumference()
    {
       return 3.1415926*2*radius;             printInfo est une méthode publique
    }                                 (sans paramètres)   qui ne retourne pas de résultat,
                                          (type void), mais qui affiche un texte dans
                                                    la fenêtre des messages
    public void printInfo()
    {
        System.out.println("I am a ball with a radius of " + radius + " cm");
        System.out.println("and a circumference of " + calculateCircumference() + " cm.");
    }
}

Observation importante :
Une méthode peut être appelée par d'autres méthodes. Ainsi on n'a pas besoin de programmer
ou de recopier plusieurs fois les mêmes opérations. En fait, c'est l'utilité principale d'une
méthode : le code devient plus compact, plus structuré et plus lisible.
Ici, la méthode printInfo fait appel à la méthode calculateCircumference pour obtenir la
valeur de la circonférence de la balle. Le résultat retourné par la méthode
calculateCircumference est intégré directement dans l'instruction d'affichage.

[ver. 26 sept. 2018]                      Page 14 de 47
3GIG           Introduction à la programmation orientée objet           CNPI-Gdt-PrograTG'17

Discussion d'un exemple :
Créez la classe suivante:
public class Ball
{
     private double radius = 23.9;

       public double calculateCircumference()
       {
         return 3.1415926*2*radius;
         System.out.println("My circumference is " + 3.1415926*2*radius);
       }
}

Essayez de compiler la classe Ball et d'en créer une instance.

Notez vos observations et vos explications :

..............................................................................................

..............................................................................................

..............................................................................................

..............................................................................................

..............................................................................................

Pour avancés :

Quelle est la différence fondamentale entre l'instruction System.out.println et l'instruction
return ? Que peut-on dire de l'utilité de l'instruction System.out.println à l'intérieur de la
méthode calculateCircumference?

..............................................................................................

..............................................................................................

..............................................................................................

..............................................................................................

..............................................................................................

                                        Page 15 de 47                           [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17              Introduction à la programmation orientée objet           3GIG

Exercice résolu :
     •    Ouvrez votre projet '00_Exercice_resolu' dans votre dossier Java.
     •    Ajoutez la méthode publique calculateDiameter comme définie ci-dessus.
     •    Ajoutez    la  méthode    publique   calculateCircumference       sans    l'instruction
          System.out.println().
     •    Ajoutez la méthode publique printInfo comme définie ci-dessus.
     •    Compilez et créez une nouvelle instance du nom de mikesBasketBall de la classe
          Ball.
     •    Appelez les méthodes calculateDiameter, calculateCircumference et printInfo de
          l'objet mikesBasketBall.
     •    Répétez les deux points ci-dessus pour larasTennisBall et bobsVolleyBall. Que
          remarquez-vous?

Conclusions :
     •    Si la classe Ball possède un attribut radius, alors chaque instance de la classe
          (larasTennisBall, mikesBasketBall, bobsVolleyBall, …) possède cet attribut, mais
          la valeur de cet attribut peut être différente pour chaque instance :

          (Nous allons voir dans les chapitres suivants comment donner des valeurs différentes
          aux attributs des différentes instances.)
     •    Si la classe Ball possède une méthode calculateCircumference, alors chaque
          instance de la classe (larasTennisBall, mikesBasketBall, bobsVolleyBall, …)
          possède cette même méthode. Ainsi la circonférence de toutes les balles est calculée
          d'après la même formule.

L'environnement de développement (Unimozer)

Lorsque nous appelons une méthode (qui n'est pas du type void) dans notre environnement
de développement, alors le programme nous présente confortablement le résultat dans une
fenêtre de dialogue. Voilà un luxe qui est spécifique à Unimozer et que nous ne trouvons pas
dans d'autres environnements de développement. En général, le contenu des attributs se
trouve caché dans la mémoire de l'ordinateur et les résultats fournis par une méthode passent
de façon invisible d'une méthode à une autre. (Pour visualiser des valeurs, nous devrions
employer l'instruction System.out.println ou programmer nous même une fenêtre de
dialogue).

Ainsi nous pouvons considérer notre interface de développement comme une sorte de banc
d'essai et d'analyse confortable qui nous permet de visualiser et de tester nos classes avant de
les intégrer dans un programme fini.

[ver. 26 sept. 2018]                     Page 16 de 47
3GIG              Introduction à la programmation orientée objet          CNPI-Gdt-PrograTG'17

1.6.         Qu'est-ce qu'un « paramètre » ?
Un paramètre est une donnée à l'aide de laquelle on peut passer une information à une
méthode. Une méthode peut avoir aucun, un ou plusieurs paramètres.
Voici les caractéristiques d'un paramètre :
    •    il est d'un certain type (→ voir chapitre 1.7) et
    •    il possède un nom.
Donnons aux balles la possibilité de changer la valeur du radius :

Le schéma UML de la classe Ball peut être étendu de la manière suivante :
Voici le code source :
public class Ball
{
     private double radius = 0;
                                                  getRadius ne possède pas de paramètres
        public double getRadius()
        {
             return radius;
                                               setRadius possède un paramètre du type double
        }

        public void setRadius (double pRadius)
        {
             radius = pRadius;           void: la méthode ne retourne pas de résultat
        }
}

Explications :
    ●    Le mot clé «public» indique qu'il s'agit d'une méthode publique, c'est-à-dire d'une
         méthode qui est utilisable par d'autres sous-programmes ou d'autres classes.
    ●    Le mot clé «void» indique que la méthode setRadius ne retourne pas de résultat.
    ●    Le mot «setRadius» est le nom de cette méthode.
    ●    «double pRadius» est la déclaration du paramètre. Dans notre cas il contiendra la
         nouvelle valeur pour le rayon:
         ◦    « double » indique que le type du paramètre est un nombre décimal.
         ◦    « pRadius » est le nom du paramètre. Comme les noms des méthodes et des
              attributs, les noms des paramètres en Java sont écrits en lettres minuscules. Si le
              nom se compose de plusieurs mots, la première lettre de chaque mot est écrite en
              majuscules, sauf pour le premier mot.
         ◦    Pour mieux distinguer les paramètres des attributs, nous allons dans ce cours
              commencer les noms des paramètres par un 'p'.

                                            Page 17 de 47                          [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17               Introduction à la programmation orientée objet              3GIG

Autre exemple :
Prenons la classe Point et ajoutons la possibilité de modifier sa position :

public class Point
{
     private double x = 0;
     private double y = 0;

         public void setCoordinates(double pX, double pY)
         {
              x = pX;
              y = pY;
         }

}
Comme déjà indiqué, une méthode peut avoir plusieurs paramètres. Dans ce cas, les
paramètres sont séparés par une virgule. Il faut indiquer pour chaque paramètre de quel type
il s'agit. Dans le cas de la méthode setCoordinates, les deux paramètres sont des nombres
réels (type double).

Exercice résolu :
     •    Ouvrez votre projet 00_Exercice_resolu que vous avez créé auparavant.
     •    Ajoutez à la classe Ball la méthode calculateVolume qui calcule et retourne le volume
          (en cm3) de la balle.
     •    Ajoutez un attribut pressure (nombre décimal, valeur initiale 0) à la classe Ball.
     •    Ajoutez une méthode setPressure à la classe, qui sert à modifier l'attribut pressure.
     •    Complétez la méthode printInfo.
     •    Créez une instance de la classe Ball et testez les nouvelles méthodes. (Consultez
          Internet pour trouver des valeurs réalistes pour les pressions des balles de tennis,
          volleyball, basketball,...)

[ver. 26 sept. 2018]                       Page 18 de 47
3GIG            Introduction à la programmation orientée objet              CNPI-Gdt-PrograTG'17

Remarque avancée : Objets comme paramètres
Un paramètre peut avoir un type simple (int, double, boolean, …), mais un paramètre peut
aussi être un objet (p.ex. du type Rectangle, Point, …).

Exemple :
On pourrait par exemple imaginer une méthode calculateDistanceTo qui calcule la distance
entre deux instances du type Point :
public class Point
{
     private double x = 0;
     private double y = 0;

       public void setCoordinates(double pX, double pY)
       {
            x = pX;
            y = pY;
       }

       public double calculateDistanceTo(Point pOtherPoint)
       {
            return Math.sqrt(
                          Math.pow(pOtherPoint.x-x,2)+
                          Math.pow(pOtherPoint.y-y,2));
       }
}
D'après le cours de mathématiques, la distance entre les points      A x A , y A    et   B  xB , yB 
                                                 2               2
se calcule suivant la formule :   AB= x B −x A  y B− y A

Pour les détails concernant la classe Math, veuillez vous référer au chapitre 1.13

Pour tester la méthode, il faut créer deux objets point0 et point1 du type Point. Ensuite, on
peut appeler la méthode calculateDistanceTo de point0 et fournir comme paramètre le nom
de la deuxième instance point1.

Dans cet exemple, la méthode va retourner la valeur 1.4142...

                                          Page 19 de 47                                [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17                Introduction à la programmation orientée objet          3GIG

1.7.        Qu'est-ce qu'un « type » ?
Un ordinateur sait traiter différentes sortes de données. En travaillant avec un tableur
(Excel/Calc), vous avez certainement déjà remarqué qu'il faut faire la différence entre des
données numériques et du texte. En plus, vous avez vu que l'ordinateur sait faire des
opérations différentes avec du texte qu'avec des nombres et que le programme est très
sensible si on essaie de mélanger différentes sortes de données.
En général, on parle de « type » ou de « type de donnée ». En effet, dans un langage de
programmation évolué comme Java, toutes les données sont typisées, c.-à-d. le type de
chaque donnée doit être fixe et connu à l'avance.
Le type d'une donnée définit :
     •    de quelle sorte de donnée il s'agit (nombre entier, nombre décimal, texte, …),
     •    dans quel domaine la valeur de la donnée peut varier,
     •    combien de place la donnée occupe dans la mémoire de l'ordinateur,
     •    quelles opérations peuvent être effectuées sur cette donnée.

En Java, on distingue les types de base suivants :

Les nombres entiers :
    •     byte         8 bits    [-128 … 127]
    •     short        16 bits   [-32'768 … 32'767]
    •     int          32 bits   [-2'147'483'648 … 2'147'483'647]
    •     long         64 bits   [-9'223'372'036'854'775'808 … 9'223'372'036'854'775'807]

Les nombres décimaux (valeurs négatives et positives) :
    •     float        32 bits   [1,4·10-45 … 3,4·1038]
    •     double       64 bits   [4,9·10-324 … 1,79·10308]

Les booléens :
    •     boolean      1 bit          {true, false}

Remarques :
     •    La plupart du temps, nous allons employer le type int pour des entiers et le type
          double pour des nombres décimaux.
     •    Pour traiter des textes, on emploie le type String qui n'est pas un type de base et qui
          sera traité plus tard dans un chapitre à part. On peut cependant déjà noter que dans un
          programme Java les textes sont à noter entre guillemets : "…"
          (p.ex. : streetName = "rue Bellevue"; )
          On peut concaténer (coller ensemble) des textes avec le symbole d'addition «+» .

[ver. 26 sept. 2018]                        Page 20 de 47
3GIG               Introduction à la programmation orientée objet           CNPI-Gdt-PrograTG'17

Exemple : la classe Rectangle

public class Rectangle
{

        private int width = 0;
        private int height = 0;

        public int getCircumference()
        {
             return 2 * (width+height);
        }

        public double calculateLengthOfDiagonal()
        {
             return Math.sqrt(width*width + height*height);
        }

        public String toString()
        {
             return "Rectangle, width:" + width + ", height:" + height;
        }

        public boolean isSquare()
        {
             return (width==height);
        }
}

Explications :
    ●    La méthode getCircumference retournera un entier (type int).
    ●    La méthode calculateLengthOfDiagonal utilise le théorème de Pythagore pour
         calculer la longueur de la diagonale. La racine carrée est calculée à l'aide de la méthode
         prédéfinie Math.sqrt (→ voir chapitre 1.13) qui peut prendre des entiers ou des
         décimaux comme paramètres, mais qui retourne toujours un nombre décimal comme
         résultat. Ainsi la valeur retournée par calculateLengthOfDiagonal doit être du type
         double.
    ●    La méthode toString retourne une description textuelle de l'objet et aura donc un
         résultat du type String.
         Remarque :
         Habituellement toutes les classes en Java contiennent une méthode toString qui
         donne une description textuelle des objets.
    ●    La méthode isSquare teste si le rectangle est carré ou non. La réponse à la question
         est soit vrai (true), soit faux (false), ce qui correspond au type de retour boolean. Le
         test1 (width==height) fournit une valeur booléenne qui est directement retournée
         comme résultat.

1   Voir aussi chapitre 3.2 sur les opérateurs de comparaison

                                                  Page 21 de 47                     [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17                    Introduction à la programmation orientée objet                         3GIG

1.8.        Conventions de noms pour les méthodes
Dans les exemples précédents, nous avons employé différents préfixes pour relever le rôle de
différentes méthodes. Avec ces noms, nous avons suivi les conventions de noms qui existent
pour les identifiants des méthodes en Java :

1.8.1.        Les accesseurs - préfixe get
Par le préfixe get, on désigne une méthode qui retourne directement la valeur d'un attribut.
Une telle méthode est encore appelée un accesseur. Un accesseur a toujours un type retour
différent de void. Le plus souvent, les accesseurs n'ont pas de paramètres. (Le préfixe get
peut aussi être employé pour des méthodes qui retournent une valeur dérivée des attributs par
un calcul très simple, même s'il ne s'agit pas accesseur dans le sens pur du terme 2).
Exemples : getRadius, getDiameter, getAge, getName, getX, getY

1.8.2.        Les manipulateurs - préfixe set
Par le préfixe set, on désigne une méthode qui permet de modifier directement la valeur d'un
ou de plusieurs attributs. Une telle méthode est encore appelée un manipulateur. Un
manipulateur est le plus souvent du type void et il possède un ou plusieurs paramètres. Dans
ce cours, nous supposons (sans vérification) que les données fournies correspondent toujours
au domaine de définition de la classe. Si l'utilisateur fournit des données incorrectes, la classe
se trouve dans un état inconsistant et les résultats sont imprévisibles.3
Exemples : setDiameter, setTime

1.8.3.        Les méthodes effectuant un calcul - préfixe calculate
Par le préfixe calculate, on désigne une méthode qui réalise un calcul plus complexe et
retourne le résultat de ce calcul.
Exemples : calculateSumOfDivisors, calculateGreatestCommonDivisor

1.8.4.        Les méthodes booléennes - préfixes is/has
Pour rendre le code plus lisible, les méthodes et accesseurs qui retournent une valeur
booléenne (et les variables de type booléen) portent de préférence les préfixes is ou has.
Plus rarement on peut même trouver des préfixes comme can, was, allows, ...
Exemple : isSquare, isEven, isRunning, hasWheels, hasHitAWall, canFly

1.8.5.        La méthode toString
En Java, en principe tous les objets peuvent être 'affichés' à l'aide de System.out.println ou
concaténés avec un texte. Dans ces cas, Java appelle automatiquement la méthode toString
de l'objet. Ainsi, tous les objets possèdent directement ou indirectement une méthode
toString qui retourne les informations de base de l'objet sous forme d'un texte. Ces
informations sont en général les valeurs actuelles des attributs principaux. La méthode
toString n'a jamais de paramètres et elle retourne toujours une valeur du type String.
Exemple : Rectangle.toString (→ voir chapitre 1.7)

2   En effet, pour l'utilisateur des méthodes d'une classe il n'est pas nécessaire de savoir si c'est le rayon qui est
    mémorisé (et que le diamètre est dérivé du rayon) ou si c'est l'inverse...
3   Dans des programmes professionnels de telles erreurs sont évitées par le lancement et le traitement
    d'exceptions. Le concept d'exceptions ne fait pas partie du cours de la formation technique générale.

[ver. 26 sept. 2018]                              Page 22 de 47
3GIG             Introduction à la programmation orientée objet              CNPI-Gdt-PrograTG'17

1.9.      Qu'est-ce qu'un « constructeur » ?

Le « constructeur » est la méthode qui est appelée lors de la construction d'un objet. Il s'agit
d'une méthode spéciale dont le rôle est d'initialiser les attributs et sous-objets de la classe
afin de mettre l'objet dans son état initial.
Ce qu'il faut savoir à propos du constructeur :

       • Tout constructeur porte toujours le nom de la classe.

       • Un constructeur n'a pas de type de retour.

       • Un constructeur peut avoir des paramètres.

       • Un constructeur doit être public ( public ).

       • La définition d'un constructeur n'est pas obligatoire.

       • Une même classe peut posséder plusieurs constructeurs.
          Attention : Les différents constructeurs d'une classe ne peuvent pas avoir la même
          liste de paramètres : Ou bien le nombre de paramètres doit être différent ou bien au
          moins l'un des paramètres doit avoir un type différent. (Les noms des paramètres ne
          jouent pas de rôle pour la différenciation.)

Voici l'exemple de la classe Point définie précédemment :

Le code source du constructeur est le suivant :
public class Point
{
     private double x;                                                 Le compilateur Java
     private double y;                                            reconnaît le constructeur au
                                                                    fait qu'il a le même nom
       public Point(double pX, double pY)                         que la classe et qu'il n'a pas
       {                                                                  de type retour.
            x = pX;
            y = pY;
       }
}

Le constructeur Point(double pX, double pY) initialise le point lors de la création d'un
objet du type Point et assure de ce fait que ses coordonnées soient toujours initialisées.
L'initialisation des attributs se fait souvent dans le constructeur.

Remarque : Comme pour les manipulateurs (→ voir chap. 1.8.2), nous supposons dans ce
cours (sans vérification) que les données fournies correspondent toujours au domaine de
définition de la classe. Si l'utilisateur fournit des données incorrectes, l'objet se trouve dans un
état inconsistant et les résultats sont imprévisibles.

                                          Page 23 de 47                              [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17                 Introduction à la programmation orientée objet              3GIG

1.10.          Qu'est-ce qu'une « variable » ?
Une variable nous aide en général à mémoriser temporairement une donnée lors d'un calcul ou
d'une autre opération à l'intérieur d'une méthode. Une variable est déclarée dans le corps
d'une méthode et elle n'est accessible que dans ce bloc de cette méthode et à partir de la ligne
dans laquelle elle est déclarée. On regroupe souvent toutes les déclarations de variables tout
au début d'une méthode.
Résumons les caractéristiques d'une variable :

         • une variable est d'un certain type,

         • elle possède un nom,

         • elle peut être initialisée lors de sa déclaration (comme un attribut),

         • elle est connue uniquement dans le bloc de sa déclaration à l'intérieur d'une méthode.

Comparaison : Une variable est assez similaire à un paramètre ou un attribut, mais
     •     un attribut est une propriété fondamentale de la classe. Il est déclaré au début de la
           classe et il est accessible partout dans toutes les méthodes de la classe,
     •     un paramètre sert à fournir des données à une méthode lors de son appel. Il est
           déclaré dans l'en-tête de la méthode et n'est connu que dans cette méthode.
     •     une variable sert à mémoriser temporairement une valeur. Elle n'est connue que dans
           un domaine restreint de la méthode et son rôle dans le programme est très limité.

Voici l'exemple de la classe Point à laquelle on a rajouté la méthode swapCoordinates. Cette
méthode échange les valeurs des coordonnées x et y :

public class Point
{                                                                  attributs de la classe
     private double x = 0;
     private double y = 0;
                                                                   cette méthode ne
         public void swapCoordinates()                         possède pas de paramètres
         {
              double temp = x;
              x = y;                                                  déclaration d'une
              y = temp;                                             variable de la méthode
         }
}

Explications et remarques :
     ●     La variable temp est du type double, donc un nombre réel. Dans cet exemple, elle est
           initialisée lors de sa déclaration.
     ●     Les trois lignes de code servent à échanger les valeurs des coordonnées à l'aide d'une
           variable temporaire.
     ●     Comme pour les attributs, il est possible de déclarer une variable sans l'initialiser :
                       double temp;

[ver. 26 sept. 2018]                         Page 24 de 47
3GIG             Introduction à la programmation orientée objet             CNPI-Gdt-PrograTG'17

Reprenons la classe Point et ajoutons une méthode ayant besoin de paramètres :

public class Point
{
                                                                attributs de la classe
     private double x = 0;
     private double y = 0;

        public Point(double pX, double pY)
        {
             x = pX;
             y = pY;
        }

        public void setCoordinates(double pX, double pY)
        {
             x = pX;
             y = pY;
        }
                                                            à partir d'ici, cette
        public void swapCoordinates()                      méthode possède une
        {
                                                             variable “temp”
             double temp = x;
             x = y;
             y = temp;
                                                     à partir d'ici, la variable “temp”
        }
                                                               n'existe plus
        public void move(double pDeltaX, double pDeltaY)
        {
             x = x + pDeltaX;                            cette méthode
             y = y + pDeltaY;                    possède les deux paramètres
        }                                            “pDeltaX” et “pDeltaY”
                                                       et change les attributs “x” et “y”
}

Explications :
    ●    La méthode move ajoute des valeurs aux attributs afin de déplacer le point.
    ●    Veuillez noter que sans explications, le code n'est pas très compréhensible. Afin d'éviter
         une telle situation, on préfère ajouter des commentaires au code source (→ voir
         chapitre 2.1).

                                           Page 25 de 47                            [ver. 26 sept. 2018]
CNPI-Gdt-PrograTG'17               Introduction à la programmation orientée objet            3GIG

1.11.          Opérateurs, compatibilité et conversions
Dans les exemples précédents, vous avez déjà retrouvé les opérateurs standards qui vous sont
familiers ( + , - , * , / ). Complétons la liste et donnons quelques précisions.

1.11.1.          Opérateur d'affectation « = »

Exemple :
   seconds = minutes*60 + hours*3600;

Effet : La partie qui se trouve à droite du signe d'égalité est évaluée et le résultat est affecté
(mémorisé) dans la variable (ou l'attribut) qui se trouve à gauche du signe d'égalité.
Il faut que les types des deux parties soient compatibles, c.-à-d que leurs types doivent être
égaux ou que le type du résultat à droite doit être un type 'plus petit' que le type à gauche.
P. ex. on peut affecter simplement une valeur du type int à une variable du type long ou
double, mais pas inversement. Sinon il faut forcer la conversion (→ voir chapitre 1.11.3) vers
un type plus petit.

Exemples :
       double x = 123.3;
       int i = 102;
       i = x;          // impossible !!
       i = (int)x;     // conversion forcée avec perte de précision : i sera 123
       x = i;          // pas de problèmes !

Remarque pour avancés :
En Java, il existe des opérateurs d'affectation qui effectuent en même temps un calcul
( ++ , += , *= , … ). Il n'y a aucune nécessité de les utiliser dans ce cours, mais si cela vous
intéresse, vous trouvez des précisions dans tous les livres ou sites sur Java.

1.11.2.          Opérateurs arithmétiques
                           +    addition
                           -    soustraction
                           *    multiplication
                           /    division (entière et rationnelle !)
                           %    modulo (reste d'une division entière)

Exemples:
         2.5 / 2.0     →       1.25            division de réels       → résultat réel
         20 / 7        →       2               division d'entiers      → résultat entier
         20 % 7        →       6               le reste de la division de 20 par 7 donne 6
                                               En effet : 20 = 2 · 7 + 6

                                                      partie entière   reste

[ver. 26 sept. 2018]                        Page 26 de 47
Vous pouvez aussi lire