ICS3U

Accueil > Programmer avec Java >

Méthodes donnant une valeur de retour

Survol et attentes

Définitions
Implémenter
En programmation, ce terme veut dire “écrire le code selon le plan pour le programme”. Avec les programmes modulaire, l’implémentation se fait une méthode à la fois afin de tester que chaque morceau fonctionne correctement avant de passer au suivant.
Déclaration de méthode
signature spécifiant le type de retour, le nom, les paramètres et le bloc de code d’une fonction.
Corps de méthode
tout entre les accolades {} qui suivent directement la signatures de la méthode. Les méthodes implémentées doivent toujours avoir un corps; la signature n’est jamais terminée avec un ;.
Appel de méthode
instruction qui utilise le nom de la méthode suivi par des parenthèses. Si la méthode retourne une valeur, on l’assigne souvent à une variable ou on l’utilise directement dans le reste de l’instruction, comme un calcul ou un affichage. Si la méthode reçoit aussi de l’information, on passe ces valeurs entre les parenthèses.
Valeur de retour
valeur produit par une méthode et renvoyée au programme. L’appel de méthode représente essentiellement cette valeur dans l’expression où l’appel est insérée, p. ex. un calcul ou une assignation. Dans Java, le type de retour est spécifié dans la déclaration de la méthode devant le nom de la méthode. Les méthodes qui ne retournent rien ont le type de retour void. Les autres ont un type de retour comme les variables et incluent une instruction return [valeur]; à la fin du bloc de code de la méthode.

Objectifs d’apprentissage

À la fin de cette leçon vous devrez être en mesure de :

Critères de succès

Exemples connus de méthodes avec valeur de retour

Vous connaissez déjà quelques méthodes avec valeur de retour :

  • celles pour la classe Scanner - comme nextInt(), nextDouble(), nextLine()
  • celles pour la classe Math - comme Math.pow() et Math.sqrt()
  • celles pour la classe String - comme length() et toUpperCase()
Qu'est-ce que ces exemples ont tous en commun?

Réponse

Il y a quelques indices que ces méthodes retournent une valeur au programme appelant :

  1. On assigne souvent une variable du type approprié pour recevoir la valeur retournée, p. ex. String name = scanner.nextLine();
  2. Les info-bulles de notre éditeur nous montrent le type de retour de la méthode dans l’en-tête et décrivent la nature de la valeur retournée, p. ex. : info-bulle pour nextInt()

Exemples connus de méthodes sans valeur de retour

Les méthodes sans valeur de retour ont le type de retour void. Elles sont souvent utilisées pour des actions qui modifient directement l’état de la mémoire du programme ou qui font des sorties (comme afficher à l’écran ou enregistrer dans un fichier).

Ceux que vous connaissez le mieux sont les méthodes :

  • main - qui ne retourne rien au système d’exploitation : sa fin est la fin du programme
  • println, print et printf de System.out - qui affichent des messages à la console

Il y a quelques indices que ces méthodes ne retournent pas de valeur :

  1. On ne déclare aucune variable pour recevoir la valeur retourné (car il n’y en a pas)
  2. Le mot-clé void précède immédiatment le nom de la méthode dans la déclaration, p. ex. void main() ou sa version plus standard public static void main(String[] args)

Écrire nos propres méthodes avec valeur de retour

Avec la décomposition, on a vu que c’est souvent utile de diviser un programme complet et plus petits sous-problèmes. Chacun serait une (ou plusieurs) méthode(s). Il faut alors savoir comment les déclarer dans nos programmes.

Signature de méthode

L’exemple de la leçon précédente, dans MainClass.java, montre comment déclarer les méthodes sans valeur de retour - comme void main() et void welcome(). C’est la même chose pour les méthodes avec valeur de retour, sauf qu’on remplace void par le type de retour désiré. Le format général est alors :

1
2
3
[type de retour] [nom de la méthode]() {
    // bloc de code
}

Corps de méthode

Les corps de méthode, les blocs de code entre les accolades {}, seront différents selon si le type est void (pas de valeur de retour) ou non.

Sans valeur de retour

Type : void

1
2
3
void [nom de la méthode]() {
    // instructions
} // retour implicite à l'accolade fermante

ou

1
2
3
4
void [nom de la méthode]() {
    // autres instructions
    return; // retour explicite sans valeur de retour
}

Avec valeur de retour

Type : int, double, String, etc.

1
2
3
4
[type de retour] [nom de la méthode]() {
    // autres instructions
    return [valeur]; // retour explicite où valeur est du type de retour
}

Deux exemples

Le programme ci-dessous montre un exemple très simple (et banal) de deux méthodes avec valeur de retour.

Fichier : BasicReturn.java

1
2
3
4
5
6
7
8
9
10
11
12
13
String getName() {
    return "Dave3000";
}

int getMeaningOfLife() {
    return 42;
}

void main() {
    String name = getName();
    System.out.println("Bonjour, je m'appelle " + name);
    System.out.println("J'ai aussi un chiffre très important pour vous : " + getMeaningOfLife());
}

Remarquez qu’on a placé la méthode main à la fin du fichier. C’est possible de le faire, et souvent très naturel de le faire si vous avez planifié les différents modules de votre programme avant de commencer. Les développeurs tendent à mettre la méthode main soit au début, soit à la fin du fichier pour faciliter la lecture du programme.

String getName()

  • Type de retour : String : retourne "Dave3000", un String littéral
  • Quand on l’appelle dans main (ligne 10), on assigne la valeur retournée à la variable name, qu’on affiche ensuite à la ligne 11.

int getMeaningOfLife()

  • Type de retour : int : retourne 42, un int littéral
  • Quand on l’appelle dans main (ligne 12), on affiche directement la valeur retournée sur cette même ligne. Notez que le nom de la méthode est tout de même suivi de parenthèses.

void main()

  • Type de retour : void : ne retourne rien
  • retourne implicitement à la fin de la méthode (sans instruction return)

Diagramme de flux pour une méthode avec valeur de retour

Ce qu’on a déjà appris sur les diagrammes de flux pour les méthodes s’applique, mais il faut maintenant :

  1. Indiquer dans la définition de la méthode ce qui sera retourné
  2. Utiliser dans l’algorithme principal ce qui est retourné suite à l’appel de la méthode

Voici le diagramme de flux pour le programme BasicReturn.java :

diagramme de flux pour BasicReturn

Le diagramme de flux nous aide à mieux voir la mécanique appel-retour. On voit quelque chose là qui n’est pas aussi apparent dans le code. Dans l’algorithme principal du diagramme de flux nous devons utiliser au moins deux instructions, soit :

  • une pour l’appel de la méthode et
  • une pour utiliser la valeur de retour.

Dans le code, tout ça se fait normalement sur la même ligne de code, en combinant plusieurs expressions (p. ex. : assignation et appel, affichage et appel) dans une seule instruction.

Notez aussi que l’appel précède toujours l’autre instruction dans le diagramme (comme durant l’exécution réelle du programme). Dans le code, ce n’est pas évident que ce soit le cas, car l’appel se trouve plus à gauche que l’autre instruction.

Structure générale pour l’utilisation d’une méthode avec valeur de retour

Pour l’appel

appel d'une méthode

Pour la définition

retour d'une méthode

Tracer la séquence d’exécution

Peu importe si main se trouve au début ou à la fin du fichier, on commence toujours le programme à main. À part le déplacement de main, il n’y a rien de nouveau dans le diagramme de séquence d’exécution, sauf que :

  • le fait de retourner à la même ligne que l’appel devrait faire plus de sens;
  • on n’arrive pas à la ligne de l’accolade fermante s’il y a une instruction return; l’accolade fermante est un return implicite dans les autres cas.
1
2
3
4
5
6
7
9
10 -> 1
10 <- 2
11
12 -> 5
12 <- 6
13

Pour getName

1
10 -> 1

est l’appel

1
10 <- 2

est l’assignation de la valeur de retour à name

Pour getMeaningOfLife

1
12 -> 5

est l’appel

1
12 <- 6

est l’affichage de la valeur de retour

Diagramme de dépendances

Encore, pour ce diagramme on doit commencer à main et regarder quelles méthodes il appelle.

La nouveauté est qu’avec des valeurs de retour, on inclut le type de retour dans le bloc de la méthode. Plusieurs styles sont possibles, mais deux qui sont cohérents avec ce que nous voyons sont :

  • [nom de la méthode]() -> [type de retour] … la flèche est semblable à ce qu’on utilise dans le diagramme de séquence d’exécution
  • [nom de la méthode]() : [type de retour] … ce format ressemble à ce que vous voyez si vous ouvrez la panneau Structure (Outline en anglais) de VS Code. structure du code dans VS Code

Voici donc une version possible de ce diagramme. L’ajout des valeurs de retour nous indique que main dépend des valeurs String et int produites par les deux méthodes qu’il appelle.

diagramme de dépendance avec valeurs de retour

Exercices

🛠️ Pratique

Travaillez dans le répertoire GitHub partagé par votre enseignant pour la pratique et les exercices

  1. Créer un fichier DeclaringMethods.java qui respecte le diagramme de dépendances ci-dessous ainsi que les détails d’implémentation suivants :
    1. showTheNumber affiche la valeur retournée de getTheNumber et ne retourne rien à main
    2. makeItCaps retourne une valeur en majuscules du texte retournée par getTheWords. Cette valeur sera affichée par main. Indice: utiliser la méthode toUpperCase() pour changer la casse de lettres.
  2. Prendre une capture d’écran de la section Structure de VS Code. Quelle est le type de retour des méthodes showTheNumber et main qui ne retournent rien au programme? Conservez la capture comme ./captures/declaringMethods_structure.png
  3. Lancer le programme et prendre une capture d’écran de la session à la console. Nomme-la ./captures/declaringMethods.png.
  4. Créer un diagramme de flux nommé ./diagrams/declaringMethods.drawio pour le programme.
  5. Tracer l’exécution avec un diagramme de séquence d’exécution que vous écrivez dans le commentaire d’en-tête du code source.

diagramme de dépendance pour la pratique