Méthodes Java et décomposition d’un programme

Apprends à écrire tes propres méthodes statiques en Java et à construire des programmes à partir de ces méthodes. Définis et appelle des méthodes, transmets-leur des informations par des paramètres et récupère leurs résultats avec return. Découvre où chaque variable peut être utilisée, pourquoi une méthode travaille sur des copies de ses arguments et comment la pile d’appels garde la trace des méthodes en cours d’exécution. Surcharge des méthodes et prévois quelle version Java appelle. Enfin, décompose un problème en petites méthodes qui remplissent chacune une tâche, supprime le code répété, puis construis et teste un programme méthode par méthode.

DébutantUnité 3 sur 11 de la formation Formation : Java orienté objet : classes, collections, héritage et tests

Ce que tu vas apprendre

  1. Définis des méthodes statiques, appelle-les depuis main et depuis d’autres méthodes, et transmets-leur les informations nécessaires par des paramètres.
    • Définis une méthode et appelle-la
      Écris l’en-tête et le corps d’une méthode au bon endroit, appelle la méthode par son nom et suis le passage de l’exécution dans la méthode, puis son retour.
    • Transmets des informations à une méthode à l’aide de paramètres
      Déclare des paramètres avec un type et un nom, appelle la méthode avec des arguments compatibles et utilise plusieurs paramètres dans le bon ordre.
  2. Écris des méthodes qui calculent une valeur et la renvoient avec return, puis utilise les valeurs renvoyées dans des variables, des expressions et des conditions.
    • Renvoie une valeur et utilise-la
      Déclare un type de retour, renvoie un résultat avec une instruction return et décide dans le code appelant de ce que devient la valeur renvoyée.
    • Effectue un retour depuis une branche conditionnelle ou une boucle
      Utilise des instructions return dans des instructions if et des boucles, assure-toi que chaque chemin renvoie une valeur et écris des méthodes qui répondent par oui ou par non.
  3. Identifie où chaque variable peut être utilisée, ce qu’une méthode peut ou non modifier dans le code qui l’appelle et comment la pile d’appels garde la trace des méthodes en cours d’exécution.
    • Identifie où chaque variable peut être utilisée
      Applique les règles de portée des variables locales, des paramètres et des variables déclarées dans des blocs, et corrige les erreurs de compilation causées par une mauvaise utilisation de la portée.
    • Comprends que les valeurs des arguments sont transmises par copie
      Prévois ce qu’une méthode peut modifier dans le code qui l’appelle : la méthode travaille sur des copies des valeurs des arguments, donc réaffecter un paramètre ne modifie pas la variable du code appelant.
    • Suis les appels de méthodes dans la pile d’appels
      Suis la façon dont Java enregistre les méthodes en cours d’exécution dans des cadres de pile, parcours des programmes dans lesquels des méthodes en appellent d’autres et lis une trace de pile.
  4. Donne le même nom à plusieurs méthodes ayant des listes de paramètres différentes et prévois quelle version Java appelle pour un ensemble d’arguments donné.
    • Écris des méthodes surchargées
      Déclare des méthodes qui portent le même nom, identifie les différences qui rendent une surcharge valide et utilise la surcharge lorsque les méthodes accomplissent la même tâche.
    • Prévois quelle méthode surchargée sera exécutée
      Détermine quelle version Java choisit à partir des types des arguments, notamment en cas de conversion élargissante automatique, et reconnais les appels qui ne compilent pas.
  5. Décompose un problème en petites méthodes qui remplissent chacune une tâche, remplace le code répété par des méthodes paramétrées, puis construis et teste un programme méthode par méthode.
    • Attribue une tâche précise à chaque méthode
      Reconnais un programme bien décomposé, divise le code qui en fait trop et sépare les calculs des entrées-sorties.
    • Remplace du code répété par une méthode paramétrée
      Repère du code répété avec de petites différences, transforme-le en une méthode dont les paramètres portent ces différences et vérifie que le comportement du programme reste identique.
    • Conçois un programme par décomposition descendante et teste-le méthode par méthode
      Planifie un programme sous forme d’une suite d’appels de méthodes, écris-le étape par étape avec des bouchons temporaires et teste chaque méthode avec des données dont tu connais les résultats.

Méthodes Java : cours

5 chapitres

1

Écris et appelle tes propres méthodes

Un programme devient plus facile à suivre lorsque ses étapes utiles portent des noms. Une méthode donne un nom à un groupe d’instructions et un appel exécute ces instructions à l’endroit où elles sont nécessaires. Commence par une méthode qui affiche toujours la même ligne, puis ajoute des paramètres pour qu’une seule définition puisse traiter différentes entrées. Lire un en-tête et le mettre en correspondance avec un appel te permet de voir les informations nécessaires à chaque étape avant d’examiner son corps.

1.1 Définis une méthode et appelle-la

Une méthode est un bloc d’instructions nommé qui accomplit une tâche. Définir une méthode rend cette tâche disponible ; l’appeler exécute la tâche.

Lis l’en-tête et le corps
public static void printLine() {
    System.out.println("----------");
}

La première ligne est l’en-tête. Lis ses éléments de gauche à droite :

  • public permet au code d’autres classes d’appeler la méthode.
  • static fait appartenir la méthode à la classe. Aucun objet n’est nécessaire pour l’appeler.
  • void indique que la méthode ne renvoie aucune valeur.
  • printLine donne un nom à la tâche.
  • () est la liste vide des paramètres : cette méthode n’a besoin d’aucune donnée en entrée.

Les accolades entourent le corps, c’est-à-dire les instructions exécutées lors d’un appel. Il n’y a pas de point-virgule entre cet en-tête et son accolade ouvrante.

Place la définition dans la classe
public class Main {
    public static void main(String[] args) {
        System.out.println("Start");
        printLine();
        System.out.println("Middle");
        printLine();
    }

    public static void printLine() {
        System.out.println("----------");
    }
}

main et printLine sont deux méthodes distinctes dans Main. L’accolade fermante de main précède la définition de printLine. Une méthode ne peut pas être définie dans une autre méthode ; une accolade mal placée peut produire « illegal start of expression ».

Les définitions peuvent apparaître dans l’un ou l’autre ordre. Déplacer printLine au-dessus de main ne change pas le moment où elle s’exécute. Une méthode qui n’est jamais appelée ne s’exécute pas simplement parce que sa définition figure dans le fichier.

Suis un appel et le retour au code appelant

L’appel printLine(); comprend le nom, les parenthèses et un point-virgule, car l’appel constitue une instruction à lui seul. L’exécution commence dans main :

  1. Afficher « Start ».
  2. Entrer dans printLine, afficher dix tirets, puis reprendre après l’appel.
  3. Afficher « Middle ».
  4. Entrer à nouveau dans printLine et afficher à nouveau dix tirets.

La sortie est :

Start
----------
Middle
----------

Les deux appels utilisent la même définition. Modifier la ligne qu’elle affiche modifie les deux endroits où elle est utilisée.

Nomme et appelle les méthodes correctement

Utilise un verbe ou un groupe verbal en camelCase, en commençant par une minuscule : printReceipt, calculateAverage ou isValidCode. Java distingue les majuscules des minuscules : PrintLine() ne trouve pas une méthode nommée printLine. Écrire printLine; échoue également ; les parenthèses font partie de l’appel.

Pour une méthode statique d’une autre classe, écris d’abord le nom de la classe. Math.max(3, 8) donne 8, Math.abs(-4) donne 4 et Math.sqrt(16.0) donne 4.0. Tes propres méthodes dans la même classe peuvent être appelées par leur seul nom.

Ces exemples utilisent la forme classique fondée sur une classe avec public static void main(String[] args). Java 25 prend aussi en charge les fichiers source compacts avec void main() et sans classe englobante. Garde la forme classique pour exécuter ces exemples ; ses méthodes auxiliaires sont déclarées static. Les méthodes que tu appelles depuis la bibliothèque Java, comme System.out.println, n’ont pas nécessairement à être statiques elles-mêmes.

Points clés

  • Place les définitions de méthodes dans la classe et en dehors des autres méthodes.
  • Une définition rend une tâche disponible ; un appel l’exécute, puis l’exécution reprend dans le code appelant.
  • Écris des parenthèses dans un appel et un point-virgule lorsque l’appel constitue une instruction.
  • Utilise un nom descriptif en camelCase et respecte exactement les majuscules et les minuscules.
  • Appelle une méthode statique d’une autre classe avec le nom de sa classe, comme dans Math.max(3, 8).

1.2 Transmets des informations à une méthode à l’aide de paramètres

Un paramètre permet à une méthode de traiter des valeurs qui changent d’un appel à l’autre. Un argument est la valeur fournie pour ce paramètre lors de l’appel de la méthode.

Donne un type et un nom à chaque entrée
public static void printStars(int count) {
    for (int i = 0; i < count; i++) {
        System.out.print("*");
    }
    System.out.println();
}

int count déclare un paramètre. Dans printStars(3);, l’argument 3 devient la valeur initiale de count. La boucle s’exécute trois fois et affiche donc ***, puis println() termine la ligne. printStars(8); utilise le même corps avec count égal à 8.

Le type s’écrit dans la définition, pas dans l’appel. Écris printStars(5);, pas printStars(int 5);.

Évalue les arguments avant d’entrer dans le corps

Un argument peut être un littéral, une variable ou une expression :

int n = 4;
printStars(n * 2);

Java évalue d’abord n * 2. Il transmet la valeur obtenue, 8 : le corps commence donc avec count égal à 8. Le nom de la variable du code appelant n’a pas besoin de correspondre à celui du paramètre.

Fais correspondre plusieurs paramètres par position

Chaque paramètre doit avoir son propre type. Une méthode qui dessine un rectangle peut commencer par cet en-tête :

public static void printRectangle(int width, int height)

L’appel printRectangle(5, 2); donne à width la valeur 5 et à height la valeur 2. Inverser les arguments donne un rectangle de 2 de large et 5 de haut. Les deux appels compilent car les deux arguments sont des int ; seule la forme voulue permet de savoir quel ordre est correct. Écrire (int width, height) dans l’en-tête échoue car aucun type n’est déclaré pour height.

Des types différents rendent certaines erreurs d’ordre plus faciles à repérer :

public static void printRepeated(String text, int times) {
    for (int i = 0; i < times; i++) {
        System.out.print(text);
    }
    System.out.println();
}

printRepeated("ab", 3); affiche « ababab ». printRepeated(3, "ab"); ne peut pas correspondre à un String suivi d’un int. Le nombre d’arguments doit aussi correspondre : printRectangle(5); laisse un paramètre sans valeur.

Vérifie la compatibilité des types numériques

Java effectue automatiquement une conversion élargissante d’un int en double. Une méthode avec les paramètres (double km, double hours) accepte les arguments (150, 2) et reçoit 150.0 et 2.0. Toute valeur int peut être représentée exactement sous forme de double.

Java n’effectue pas implicitement de conversion réductrice d’un argument double pour un paramètre int. printStars(2.9); échoue car la conversion ferait perdre la partie fractionnaire. Le transtypage explicite dans printStars((int) 2.9); produit 2 : deux étoiles sont donc affichées. Utilise un transtypage seulement lorsque tu souhaites supprimer cette partie.

Choisis un paramètre pour chaque information nécessaire à la tâche. Recevoir du texte et un nombre permet d’utiliser printRepeated avec une saisie au clavier, un appel de test fixe ou une autre méthode. Son corps n’a pas à décider d’où viennent ces valeurs.

Points clés

  • Un paramètre est déclaré dans un en-tête ; un argument fournit sa valeur dans un appel.
  • Java évalue les expressions des arguments avant d’exécuter la méthode appelée.
  • Les arguments correspondent aux paramètres par leur position, leur nombre et leur type compatible.
  • Écris un type pour chaque paramètre, mais aucun type dans l’appel.
  • Un int peut être converti par élargissement en double ; un double nécessite un transtypage explicite pour devenir un int.
  • Inverser des arguments de même type peut compiler tout en changeant le résultat.
2

Renvoie des résultats depuis des méthodes

Une méthode peut faire plus qu’afficher : elle peut renvoyer une valeur au code qui l’a appelée. Cela rend un calcul utilisable dans un autre calcul, une condition ou un compte rendu ultérieur. Suis la façon dont les types de retour, les expressions et les affectations s’articulent, puis utilise des instructions return dans des décisions et des recherches. La place d’un return compte : elle détermine à la fois la réponse transmise au code appelant et la partie de la méthode qui peut s’exécuter.

2.1 Renvoie une valeur et utilise-la

Une valeur de retour est un résultat transmis par une méthode au code qui l’a appelée. Une fois l’appel terminé, il peut être utilisé comme une expression du type de ce résultat.

Déclare ce qui est renvoyé
public static int sum(int a, int b) {
    return a + b;
}

int remplace void dans l’en-tête car cette méthode renvoie un entier. L’instruction return évalue a + b et transmet la valeur à l’endroit de l’appel. Pour sum(4, 7), cette valeur est 11.

Le code appelant décide de la suite :

int total = sum(4, 7);
System.out.println(sum(4, 7));
int doubled = sum(2, 3) * 2;

La première ligne stocke 11 ; la deuxième affiche 11 ; la troisième stocke 10. Une valeur renvoyée peut aussi être utilisée dans une condition, comme if (sum(a, b) > 10).

Un résultat int compatible peut subir une conversion élargissante lorsqu’il est renvoyé par une méthode de type double. Un résultat double ne peut pas être renvoyé par une méthode de type int sans conversion explicite appropriée.

Calcule l’expression avant de convertir le résultat
public static double average(int a, int b) {
    return (a + b) / 2.0;
}

Pour average(3, 4), le numérateur vaut 7. La division par le littéral double 2.0 donne 3.5. Si l’expression était (a + b) / 2, Java diviserait d’abord deux int et obtiendrait 3. Ce n’est qu’ensuite qu’il effectuerait une conversion élargissante de cette valeur pour renvoyer 3.0. Un type de retour double ne corrige pas une division entière déjà effectuée dans le corps.

Distingue le retour de l’affichage
Comportement de la méthodeCe que reçoit le code appelantCe qui apparaît à l’écran
return a + b; dans une méthode intLa sommeRien de la part de cette instruction
System.out.println(a + b); dans une méthode voidAucune valeurLa somme

Un appel void ne peut pas fournir une valeur dans une affectation ou un autre appel. Si printSum est de type void, int total = printSum(1, 2); échoue même si printSum affiche un nombre. Utilise une méthode qui renvoie une valeur pour les calculs et laisse le code appelant décider s’il faut l’afficher.

Renvoie du texte et des réponses par oui ou par non

Les types de retour comprennent aussi String et boolean. Une méthode de salutation peut renvoyer "Hello, " + name + "!", ce qui donne « Hello, Ana! » pour l’argument "Ana". Une méthode isEven(int n) peut renvoyer n % 2 == 0.

Une méthode de formatage transforme un nombre en texte réutilisable :

public static String formatDuration(int minutes) {
    return minutes / 60 + " h " + minutes % 60 + " min";
}

Pour 135, la division entière donne 2 heures entières et le reste donne 15 minutes. Le résultat est « 2 h 15 min » ; pour 60, c’est « 1 h 0 min ».

Conserve ou combine le résultat

Un appel tel que sum(4, 7); compile, mais abandonne son résultat. Si square(x) renvoie une nouvelle valeur, utilise x = square(x); pour la stocker dans x.

Un résultat peut aussi devenir directement un argument. Dans Math.max(sum(1, 2), 4), sum(1, 2) donne d’abord 3, puis Math.max(3, 4) donne 4. Évalue l’appel interne avant d’utiliser son résultat dans l’appel externe.

Points clés

  • Le type de retour déclaré indique au code appelant quel type de résultat l’appel fournit.
  • Renvoyer fournit une valeur ; afficher montre une valeur.
  • L’expression est calculée avant que son résultat soit converti dans le type de retour.
  • Stocke une valeur renvoyée lorsque le code qui suit en a besoin ; un appel seul abandonne son résultat.
  • Une valeur renvoyée peut servir d’argument à une autre méthode.

2.2 Effectue un retour depuis une branche conditionnelle ou une boucle

Une instruction return termine immédiatement l’appel de méthode en cours. Dans une condition ou une boucle, elle quitte toujours la méthode entière, pas seulement ce bloc.

Donne une réponse à chaque chemin
public static int larger(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

larger(9, 4) renvoie 9 depuis le if. Pour larger(2, 6), le corps du if est ignoré et le return final donne 6. Des entrées égales comme (5, 5) atteignent aussi le return final, qui donne 5. Aucun else n’est nécessaire après le premier return, car ce chemin a déjà quitté la méthode.

Dans une méthode ordinaire qui renvoie une valeur, aucun chemin possible ne doit atteindre l’accolade fermante sans fournir de valeur. Une méthode qui indique le signe et ne renvoie une valeur que pour les entrées positives et négatives laisse zéro sans réponse :

public static String sign(int n) {
    if (n > 0) {
        return "positive";
    } else if (n < 0) {
        return "negative";
    }
    return "zero";
}

Le return final complète la méthode. Deux instructions if distinctes, l’une testant n > 0 et l’autre n <= 0, nécessitent toujours un return final ou une structure if/else explicite. Lorsqu’il vérifie les retours, Java ne déduit pas que ces deux comparaisons couvrent tous les entiers. Une instruction placée directement après un return inconditionnel dans le même bloc est inaccessible et rejetée.

Termine une recherche au bon moment
public static int firstMultipleOf7(int start, int end) {
    for (int i = start; i <= end; i++) {
        if (i % 7 == 0) {
            return i;
        }
    }
    return -1;
}

Pour (10, 20), la boucle rejette 10, 11, 12 et 13, puis renvoie 14. L’appel se termine sans vérifier les nombres de 15 à 20. Pour (15, 20), la boucle se termine sans trouver de correspondance : le return placé après elle donne donc -1, la valeur convenue pour signaler « non trouvé ».

Placer else { return -1; } dans la boucle entraînerait une sortie après le premier candidat rejeté. La recherche à partir de 10 signalerait alors un échec avant d’atteindre 14. Le retour signalant l’échec doit venir après l’examen de tous les candidats.

Renvoie la condition elle-même

Une comparaison produit déjà un booléen. Écris return n % 2 == 0; au lieu d’un if/else qui renvoie séparément true et false. Le nom d’une méthode booléenne commence souvent par is ou has, de sorte qu’un appel se lit naturellement dans un if.

public static boolean isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0)
        || year % 400 == 0;
}

Cette méthode renvoie true pour 2024 et 2000, mais false pour 1900 et 2023. Utilise directement if (isLeapYear(y)).

Quitte une méthode void de manière anticipée

Une méthode void utilise return; sans valeur. Par exemple, printSquareRoot(double x) peut afficher « No real square root » et se terminer immédiatement pour une entrée négative. Pour les autres entrées, elle peut afficher Math.sqrt(x), qui donne 1.5 pour 2.25. Écrire return 5; dans une méthode void échoue car son en-tête indique qu’elle ne renvoie aucune valeur.

Points clés

  • return termine immédiatement l’appel en cours, y compris lorsqu’il se trouve dans une boucle.
  • Une méthode qui renvoie une valeur ne doit pas atteindre son accolade fermante sans réponse.
  • Place le return qui signale l’échec d’une recherche après la boucle, afin que les candidats suivants puissent être vérifiés.
  • Une comparaison peut être directement renvoyée comme booléen.
  • Utilise return; sans valeur pour quitter une méthode void de manière anticipée.
  • Le code placé directement après un return inconditionnel dans le même bloc est inaccessible.
3

Suis les variables et les appels dans un programme

Un appel de méthode ne donne pas à une méthode auxiliaire accès à toutes les variables du programme. Chaque appel possède ses propres paramètres et variables locales, et Java conserve ces valeurs dans un cadre de pile distinct. Utilise la portée pour déterminer où un nom est autorisé, le passage par valeur pour prévoir ce que les affectations peuvent modifier et la pile d’appels pour suivre le travail inachevé. Ces trois notions expliquent pourquoi deux variables peuvent avoir le même nom tout en contenant des valeurs différentes.

3.1 Identifie où chaque variable peut être utilisée

La portée d’une variable est la zone du code où son nom peut être utilisé. Commence par les accolades qui entourent sa déclaration : un nom local appartient à une méthode ou à un bloc précis.

Les variables locales du code appelant restent dans celui-ci
public static void main(String[] args) {
    int price = 20;
    printDouble(price);
}

public static void printDouble(int price) {
    System.out.println(price * 2);
}

Le price de main et le paramètre price de printDouble sont des variables distinctes. L’argument fournit la valeur dont la méthode auxiliaire a besoin, qui affiche donc 40.

Supprimer le paramètre et appeler printDouble() ne permet pas à la méthode auxiliaire de lire la variable locale price de main. Son corps échouerait avec « cannot find symbol ». Appeler une méthode depuis une autre ne réunit pas leurs portées. Des méthodes différentes peuvent chacune utiliser le nom count sans que leurs variables soient liées.

Un bloc imbriqué crée une portée plus petite

Une variable locale peut être utilisée de sa déclaration jusqu’à l’accolade fermante de son bloc. Un paramètre est disponible dans tout le corps de sa méthode. Un compteur déclaré dans for (int i = 0; i < 3; i++) appartient à cette boucle ; i ne peut pas être lu après celle-ci.

Pour conserver un résultat après une boucle, déclare-le avant la boucle :

int sum = 0;
for (int i = 1; i <= 5; i++) {
    sum += i;
}
System.out.println(sum);

Les additions donnent successivement à sum les valeurs 1, 3, 6, 10 et 15. L’instruction d’affichage finale peut lire sum car le bloc englobant n’est pas terminé. i n’est nécessaire que pour la boucle et reste dans sa portée.

Déplacer int sum = 0; dans le corps de la boucle crée un nouveau sum à chaque passage. Chacun commence à zéro et disparaît à la fin de ce passage. Il ne peut pas conserver une somme cumulée ni être affiché après la boucle.

Vérifie séparément les noms et les valeurs initiales

Deux variables locales de même nom ne peuvent pas avoir des portées qui se chevauchent dans une même méthode. Une méthode ayant un paramètre x ne peut pas déclarer une autre variable locale x ; une boucle qui déclare i ne peut pas déclarer un autre i dans son corps. Renomme la seconde variable ou utilise celle qui existe déjà.

Deux boucles successives peuvent chacune déclarer int i. La portée de la première boucle est terminée avant la seconde déclaration. Ce sont les accolades, et non le fichier entier, qui déterminent cette possibilité de réutilisation.

Un nom autorisé doit aussi avoir une valeur avant d’être lu. int total; total++; échoue car ++ doit lire l’ancienne valeur et une variable locale ne reçoit pas automatiquement de valeur initiale. Utilise int total = 0; pour une somme cumulée.

Garde une variable locale dans le plus petit bloc où elle est nécessaire. Si une méthode a besoin d’une information du code appelant, fais-en un paramètre. Si le code appelant a besoin d’un résultat, renvoie-le. L’en-tête et le corps de la méthode montrent alors d’où viennent ses données.

Points clés

  • Un nom local est disponible de sa déclaration jusqu’à la fin de son bloc.
  • Une méthode appelée ne peut pas lire par leur nom les variables locales du code appelant.
  • Déclare un accumulateur avant une boucle lorsqu’il doit conserver une somme ou être lu après celle-ci.
  • Les portées de noms locaux identiques ne peuvent pas se chevaucher dans une méthode, et les variables locales doivent avoir une valeur avant leur utilisation.

3.2 Comprends que les valeurs des arguments sont transmises par copie

Java transmet les arguments par valeur. Au début d’un appel, chaque paramètre reçoit une copie de la valeur de son argument. Une affectation au paramètre modifie cette variable locale.

Suis la copie séparément
public static void main(String[] args) {
    int score = 10;
    addBonus(score);
    System.out.println(score);
}

public static void addBonus(int score) {
    score = score + 5;
    System.out.println(score);
}

Il y a deux variables appelées score. Suis leurs valeurs à chaque étape :

Momentscore de mainscore de addBonus
Avant l’appel10Pas encore d’appel
À l’entrée dans addBonus1010
Après l’affectation dans la méthode auxiliaire1015
Après le retour de la méthode auxiliaire10Appel terminé

La méthode auxiliaire affiche 15, puis main affiche 10. Le fait de partager un nom ne signifie pas que les deux variables partagent leur emplacement de stockage. Renommer le paramètre ne changerait pas ce comportement.

Renvoie la nouvelle valeur et stocke-la
public static int addBonus(int score) {
    return score + 5;
}

Avec cette version, écris score = addBonus(score);. Java copie l’ancienne valeur dans le paramètre, calcule 15, renvoie cette valeur et l’affecte à la variable du code appelant. C’est l’affectation dans le code appelant qui modifie cette variable.

Un résultat peut aussi être stocké ailleurs. Si triple(int n) multiplie sa variable locale n par 3 et la renvoie, alors int a = 4; int b = triple(a); laisse a égal à 4 et donne à b la valeur 12. L’affichage de a + " " + b produit « 4 12 ».

Applique la même règle aux références String

Une variable String contient une référence à un objet String. Java copie cette référence dans un paramètre String :

public static void exclaim(String text) {
    text = text + "!";
}

Si word dans le code appelant fait référence à « hi », après exclaim(word);, word fait toujours référence à « hi ». La concaténation crée un nouvel objet String et l’affectation ne modifie que l’objet auquel le paramètre fait référence. Le contenu existant d’une chaîne String ne peut pas être modifié.

Pour conserver le nouveau texte, renvoie text + "!" depuis une méthode String telle que exclaimed, puis écris word = exclaimed(word);.

Pour les objets mutables, comme les listes, une référence copiée peut toujours désigner le même objet. Une méthode peut modifier le contenu de cet objet par l’intermédiaire de la référence copiée. Réaffecter le paramètre ne peut toujours pas faire en sorte que la variable du code appelant fasse référence à un autre objet. La règle de la référence copiée et celle du nombre copié relèvent toutes deux du passage par valeur.

Tu peux réaffecter un paramètre, mais une variable locale distincte comme result peut rendre un calcul plus long plus facile à lire : elle conserve l’entrée initiale tout en montrant quelle valeur sera renvoyée.

Points clés

  • Chaque paramètre reçoit une copie de la valeur de son argument.
  • Réaffecter un paramètre laisse inchangée la variable du code appelant.
  • Pour conserver une nouvelle valeur calculée, renvoie-la et affecte-la dans le code appelant.
  • Une référence d’objet copiée peut accéder au même objet mutable, mais la réaffectation du paramètre reste locale.

3.3 Suis les appels de méthodes dans la pile d’appels

La pile d’appels enregistre les appels qui ont commencé mais ne sont pas encore terminés. Chaque appel reçoit un cadre de pile contenant ses paramètres, ses variables locales et l’endroit où le code appelant reprendra.

Empile un cadre, termine l’appel, puis retire le cadre

La pile fonctionne selon le principe dernier entré, premier sorti. L’appel le plus récent est au sommet et s’exécute pendant que le code appelant attend en dessous. Lorsqu’il se termine, Java retire son cadre et reprend l’exécution du code appelant.

public static void main(String[] args) {
    int total = totalSeconds(2, 30);
    System.out.println(total);
}

public static int totalSeconds(int minutes, int seconds) {
    int fromMinutes = toSeconds(minutes);
    return fromMinutes + seconds;
}

public static int toSeconds(int minutes) {
    return minutes * 60;
}

Suis le travail inachevé :

  1. main démarre et appelle totalSeconds(2, 30). Son affectation à total doit attendre.
  2. Le nouveau cadre contient minutes = 2 et seconds = 30. Il appelle toSeconds(minutes) et attend la valeur de fromMinutes.
  3. toSeconds reçoit son propre minutes = 2. Elle renvoie 120 et son cadre est retiré.
  4. totalSeconds stocke fromMinutes = 120, ajoute 30 et renvoie 150. Son cadre est retiré.
  5. main stocke total = 150 et affiche 150.

Au point le plus profond, les cadres sont, de bas en haut, main, totalSeconds et toSeconds. Les deux méthodes auxiliaires ont un paramètre nommé minutes, mais ces paramètres occupent des cadres différents. Les variables locales du code appelant en attente ne deviennent pas visibles pour la méthode située au-dessus.

Un appel ultérieur reçoit un nouveau cadre. Un compteur local ne conserve pas sa valeur précédente une fois son appel terminé ; c’est la valeur de retour qui peut transmettre un résultat au code appelant.

Lis une trace de pile en partant de l’erreur

Une exception non prise en charge affiche une trace de pile qui montre où l’erreur s’est produite et quels appels y ont conduit. Voici un fichier complet :

public class Main {
    public static void main(String[] args) {
        report(300, 0);
    }

    public static void report(int meters, int minutes) {
        int speed = perMinute(meters, minutes);
        System.out.println(speed + " m per minute");
    }

    public static int perMinute(int meters, int minutes) {
        return meters / minutes;
    }
}

La première ligne de sortie est Exception in thread "main" java.lang.ArithmeticException: / by zero. Les cadres situés en dessous sont :

at Main.perMinute(Main.java:12)
at Main.report(Main.java:7)
at Main.main(Main.java:3)

Le cadre supérieur indique la division entière par zéro. Les deux suivants situent les appels qui y ont conduit. Les numéros de ligne correspondent à cette disposition précise du fichier ; ajouter une ligne les modifie.

L’espace de la pile est limité. Une chaîne qui continue d’ajouter des appels sans les laisser se terminer peut provoquer une StackOverflowError. La vue de la pile d’un débogueur te permet d’examiner cette même chaîne pendant une pause à un point d’arrêt, y compris les variables distinctes de chaque appel en attente.

Points clés

  • Chaque appel empile un nouveau cadre ; un retour retire ce cadre et reprend l’exécution du code appelant.
  • L’appel inachevé le plus récent s’exécute en premier : la pile suit le principe dernier entré, premier sorti.
  • Des variables locales de même nom dans des cadres différents sont des variables distinctes.
  • Suis le retour d’une valeur dans l’expression ou l’affectation en attente.
  • Lis une trace de pile depuis le cadre de l’erreur en haut vers les appels situés en dessous.
  • Une chaîne qui continue d’ajouter des cadres peut épuiser l’espace de la pile.
4

Surcharge des méthodes

Une opération utile peut accepter plusieurs types d’entrées. La surcharge permet à ces formes de partager un nom tout en conservant une liste de paramètres distincte pour chacune. Vérifie d’abord si deux déclarations ont réellement des signatures différentes. Suis ensuite le choix du compilateur lors d’un appel : compte les arguments, identifie leurs types et compare les versions compatibles. Le type d’une variable qui reçoit le résultat ne peut pas corriger un appel dont les arguments ne permettent pas de déterminer une surcharge appropriée.

4.1 Écris des méthodes surchargées

La surcharge consiste à donner le même nom à des méthodes dont les listes de paramètres sont différentes. Elle est utile lorsque les méthodes accomplissent la même tâche pour des entrées de nombres ou de types différents.

Compare les signatures

Pour ces méthodes, une signature se compose du nom et des types des paramètres dans leur ordre. Le nombre de paramètres découle de cette liste.

public static int max(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

public static int max(int a, int b, int c) {
    return max(max(a, b), c);
}

public static double max(double a, double b) {
    if (a > b) {
        return a;
    }
    return b;
}

Les signatures sont max(int, int), max(int, int, int) et max(double, double). max(3, 9) utilise la première et renvoie 9. max(3, 9, 5) appelle la deuxième : l’appel interne à deux int renvoie 9, puis l’appel externe à deux int compare 9 et 5 et renvoie aussi 9. max(2.5, 1.0) utilise la version double et renvoie 2.5.

Identifie les changements qui ne comptent pas

Changer uniquement le type de retour ne crée pas une surcharge. Ces en-têtes sont en conflit :

public static int area(int w, int h)
public static double area(int w, int h)

Les deux ont la signature area(int, int). Java rejette la déclaration en double. Renommer les paramètres en width et height laisse aussi la même signature : le code appelant fournit les valeurs par position, pas par nom de paramètre.

L’ordre de types différents compte. describe(String s, int n) et describe(int n, String s) ont des signatures distinctes. Elles compilent ensemble, mais le code appelant doit retenir un ordre facile à confondre ; utilise donc une telle paire seulement si elle est utile à la conception.

Laisse une surcharge plus courte fournir une valeur par défaut

Java ne fournit pas de valeurs de paramètres par défaut dans les déclarations de méthodes. Une surcharge plus courte peut appeler une version plus longue avec un argument fixe :

public static void printLine(int length, char symbol) {
    for (int i = 0; i < length; i++) {
        System.out.print(symbol);
    }
    System.out.println();
}

public static void printLine(int length) {
    printLine(length, '-');
}

printLine(5, '*'); affiche *****. printLine(4); entre dans la méthode plus courte, qui appelle la plus longue avec 4 et '-', ce qui affiche ----. La boucle ne figure qu’à un seul endroit : les modifications de la tâche d’affichage s’appliquent donc aux deux formes.

La bibliothèque Java utilise aussi des surcharges. System.out.println accepte un int, un double, un char, un boolean ou un String grâce à différentes versions. Math.abs et Math.max proposent des versions pour int, long, float et double.

Garde un seul sens pour le nom partagé. Afficher un reçu et afficher une étiquette sont des tâches différentes ; des noms clairs comme printReceipt et printLabel indiquent au code appelant quelle tâche sera accomplie.

Points clés

  • Les surcharges partagent un nom et diffèrent par le nombre, les types ou l’ordre des types de paramètres.
  • Les types de retour et les noms de paramètres ne distinguent pas les signatures.
  • Une surcharge plus courte peut appeler une version plus longue avec un argument fixe servant de valeur par défaut.
  • Utilise un même nom surchargé pour une seule tâche avec différentes formes d’entrée.

4.2 Prévois quelle méthode surchargée sera exécutée

Le compilateur choisit une surcharge à partir du nombre et des types des arguments. Détermine ce choix avant d’examiner comment la valeur renvoyée sera utilisée.

Commence par les correspondances exactes

Supposons qu’une classe définisse show(int x) et show(double x). show(5) utilise la version int car le littéral 5 est un int. show(5.0) utilise la version double. Une valeur entière écrite 5.0 reste une expression de type double.

Pour un appel avec plusieurs arguments, compare le type à chaque position. Une méthode candidate qui ne possède pas le bon nombre de paramètres ne peut pas convenir.

Accepte les conversions élargissantes si nécessaire

Si seule show(double x) existe, show(5) est valide : le int est converti par élargissement en 5.0. Les chemins de conversion élargissante des types primitifs comprennent :

byte → short → int → long → float → double
char → int → long → float → double

Avec show(long x) et show(double x), un argument int sélectionne long. C’est le type de paramètre compatible le plus spécifique : un long peut subir une conversion élargissante en double, tandis qu’un double ne peut pas subir une telle conversion en sens inverse vers long.

Une conversion élargissante est une conversion numérique autorisée ; elle ne garantit pas que chacune de ces conversions conserve tous les chiffres. En particulier, la conversion d’un long suffisamment grand en double peut arrondir sa valeur. La conversion de int en double utilisée dans les exemples précédents conserve exactement toutes les valeurs int.

Un char possède aussi une valeur numérique. Avec letter(int code) et letter(String text), letter('A') appelle la version int avec 65. Un caractère ne devient pas un String pour correspondre à un paramètre. Les guillemets doubles dans "A" produiraient en revanche un argument String.

Refuse les conversions réductrices implicites

Avec la seule version show(int x), show(5.0) échoue. Java n’effectue pas de conversion réductrice d’un argument double simplement parce que sa valeur est entière. show((int) 5.0) transmet un int après un transtypage explicite.

De même, des versions de max pour deux et trois int ne peuvent pas accepter max(1). Aucune méthode candidate n’a le nombre de paramètres requis : le compilateur indique donc « no suitable method found ». Compare la liste des méthodes candidates aux arguments fournis.

Distingue le choix de la surcharge de la conversion du résultat

Considère int twice(int n) et double twice(double x). Dans double d = twice(3);, l’argument sélectionne la surcharge int. Cet appel renvoie 6, puis l’affectation effectue une conversion élargissante en 6.0. La variable de destination d ne sélectionne pas la surcharge double.

Reconnais un appel ambigu
public static void combine(int a, double b) { }
public static void combine(double a, int b) { }

combine(1, 2) convient à la première après une conversion élargissante de son deuxième argument et à la seconde après une conversion élargissante de son premier argument. Aucune signature n’est plus spécifique sur les deux positions. Java indique « reference to combine is ambiguous » ; il ne choisit pas la définition écrite en premier.

combine(1, 2.0) ne convient qu’à (int, double), car l’autre signature nécessiterait une conversion réductrice de 2.0. Un type d’argument clair ou un meilleur ensemble de surcharges supprime l’ambiguïté.

Points clés

  • Détermine la surcharge choisie à la compilation à partir du nombre et des types des arguments.
  • Une correspondance exacte l’emporte ; une conversion élargissante peut rendre une autre version compatible.
  • Java n’effectue pas implicitement de conversion réductrice des arguments numériques d’une méthode.
  • La variable qui reçoit le résultat ne détermine pas la surcharge.
  • Un appel est ambigu lorsque plusieurs versions conviennent et qu’aucune n’est plus spécifique pour l’ensemble de l’appel.
5

Décompose un programme en méthodes

Les méthodes d’un programme doivent en révéler le plan. Donne à chaque méthode une tâche utile, transmets-lui les valeurs dont elle a besoin et utilise son résultat pour l’étape suivante. Du code répété révèle souvent qu’il manque une méthode ; une méthode longue révèle souvent que plusieurs tâches sont mélangées. Planifie d’abord les en-têtes, construis de petits éléments aux résultats connus et relie-les progressivement. Il devient ainsi plus facile de voir comment les données circulent et où se trouve un nouveau bogue.

5.1 Attribue une tâche précise à chaque méthode

La décomposition consiste à diviser un problème en tâches plus petites et à résoudre chaque tâche dans sa propre méthode. Choisis des tâches dont les noms aident à lire le plan du programme.

Sépare les calculs des entrées-sorties

Un programme sur une sortie à vélo doit calculer une vitesse et produire un compte rendu. Ces deux tâches utilisent les mêmes données, mais ont des rôles différents :

public static double kilometersPerHour(double km, double hours) {
    return km / hours;
}

public static void printRideReport(double speed) {
    System.out.println("Speed: " + speed + " km/h");
}

Pour une sortie de 150 km en 2 heures, le calcul renvoie 75.0. La méthode de compte rendu reçoit cette valeur et l’affiche. Le code appelant relie les étapes :

double speed = kilometersPerHour(150, 2);
printRideReport(speed);

La méthode de calcul ne lit aucune saisie au clavier et n’affiche aucun compte rendu. Un autre programme peut l’utiliser pour comparer des sorties ou stocker des vitesses sans modifier son corps. Pour la tester, appelle-la avec des entrées connues et compare le nombre renvoyé au résultat attendu.

Reconnais une méthode qui accomplit trop de tâches

Un nom comme readAndCheckAndPrint suggère plusieurs actions. D’autres indices comprennent des sections délimitées par des commentaires, un corps plus long qu’un écran et des groupes de variables qui servent à des tâches sans rapport. Ce sont des raisons d’examiner la méthode, pas des limites mécaniques sur le nombre de lignes qu’elle peut contenir.

Sépare les tâches à un endroit qui a un sens. Le code d’entrée peut obtenir une valeur, une méthode auxiliaire booléenne peut la vérifier, une méthode de calcul peut renvoyer un résultat et une méthode de compte rendu peut l’afficher. main se lit alors comme une courte description de la façon dont ces tâches s’enchaînent.

Les méthodes ciblées sont plus faciles à lire séparément, à réutiliser et à tester. Si le format d’un compte rendu change, modifie la méthode de compte rendu. Si un calcul est erroné, teste ce calcul sans avoir à saisir toutes les données d’une session.

Laisse l’en-tête expliquer la circulation des données

Dans kilometersPerHour(double km, double hours), le nom indique le résultat, les noms des paramètres indiquent les grandeurs et le type de retour double indique la nature de la réponse. Un court commentaire Javadoc peut préciser le sens des entrées et du résultat :

/**
 * Calculates a ride's average speed.
 * @param km distance in kilometers
 * @param hours elapsed time in hours, greater than zero
 * @return speed in kilometers per hour
 */

Place ce commentaire directement au-dessus de l’en-tête de la méthode. Un commentaire utile ajoute des informations comme les unités ou une exigence sur les entrées ; il n’a pas besoin de raconter chaque ligne du corps.

Une méthode auxiliaire nécessaire uniquement à sa propre classe peut être private static. private empêche les autres classes de l’appeler, tandis que le code de la même classe peut toujours l’utiliser. public static rend la méthode auxiliaire accessible aux autres classes.

Encapsuler chaque instruction évidente dans sa propre méthode peut aussi masquer le plan. Garde une méthode lorsque son nom représente une étape utile ou un calcul réutilisable. Une chaîne de méthodes auxiliaires qui se contentent de transmettre le même appel ajoute des endroits à examiner sans mieux expliquer la tâche.

Points clés

  • Décompose un programme en tâches utiles portant des noms clairs.
  • Les méthodes de calcul prennent des paramètres et renvoient des résultats ; les méthodes de compte rendu les affichent.
  • Les méthodes auxiliaires ciblées peuvent être réutilisées et testées séparément.
  • Un en-tête et un court commentaire Javadoc peuvent préciser les entrées, les unités et le résultat.
  • Utilise private static pour les méthodes auxiliaires que seule leur propre classe doit appeler.
  • Sépare le code là où un nom clarifie la tâche, pas à chaque instruction.

5.2 Remplace du code répété par une méthode paramétrée

Le code dupliqué répète la même tâche à plusieurs endroits. Lorsque seules les valeurs d’entrée diffèrent, une méthode paramétrée peut rassembler le travail commun.

Repère le calcul commun

Supposons qu’un programme additionne les nombres de 1 à 10, puis de 1 à 50 :

int total1 = 0;
for (int i = 1; i <= 10; i++) {
    total1 += i;
}
System.out.println("Sum 1 to 10: " + total1);
int total2 = 0;
for (int i = 1; i <= 50; i++) {
    total2 += i;
}
System.out.println("Sum 1 to 50: " + total2);

Les deux boucles commencent à 1, ajoutent des valeurs à une somme et s’arrêtent à une borne supérieure. Seule cette borne change. Un paramètre n peut la transmettre à un calcul commun.

Extrais la méthode
public static int sumUpTo(int n) {
    int total = 0;
    for (int i = 1; i <= n; i++) {
        total += i;
    }
    return total;
}

n est l’entrée qui varie. total et i sont des variables de travail qui appartiennent à la méthode auxiliaire. Le code appelant a besoin de la somme finale : la méthode auxiliaire renvoie donc un int.

Remplace les deux sections répétées :

System.out.println("Sum 1 to 10: " + sumUpTo(10));
System.out.println("Sum 1 to 50: " + sumUpTo(50));

sumUpTo(10) renvoie 55 et sumUpTo(50) renvoie 1275. Les lignes affichées sont « Sum 1 to 10: 55 » et « Sum 1 to 50: 1275 », comme avant. Les descriptions restent dans le code appelant ; la boucle effectue uniquement le calcul.

Vérifie l’extraction dans un ordre précis
  1. Repère les instructions qui effectuent la tâche répétée.
  2. Identifie chaque valeur qui diffère entre les copies.
  3. Transforme ces valeurs en paramètres de types adaptés et renvoie tout résultat nécessaire à l’extérieur.
  4. Remplace chaque copie par un appel utilisant ses entrées initiales.
  5. Exécute le programme avec les mêmes entrées avant et après, puis compare son comportement.

Modifier la structure du code tout en préservant son comportement est une refactorisation. Si une copie initiale reste en place, une correction ultérieure devra toujours être faite à deux endroits. Déplacer une instruction d’affichage dans une boucle ou modifier une borne de boucle change le comportement, même si le code est désormais plus court.

Lorsque deux différences sont de types différents, utilise des paramètres correspondants. Répéter différents textes un nombre variable de fois suggère printRepeated(String text, int times) ; le mot est un String et le nombre de répétitions est un int.

Du code d’apparence similaire n’accomplit pas toujours la même tâche. Un paramètre booléen qui fait passer une méthode d’un calcul sans rapport à un autre peut rendre ses appels difficiles à interpréter. Donne des noms distincts aux tâches distinctes. Extrais l’opération répétée uniquement lorsque faire varier ses entrées préserve un sens clair et unique.

Points clés

  • Identifie la tâche commune et transforme ses entrées variables en paramètres.
  • Garde les variables de travail locales et renvoie tout résultat dont le code appelant a besoin.
  • Refactorise chaque copie et compare le comportement avec les mêmes entrées.
  • Fusionne les copies d’une même tâche, pas des tâches sans rapport qui se ressemblent seulement.

5.3 Conçois un programme par décomposition descendante et teste-le méthode par méthode

La conception descendante part de la tâche entière et l’affine en appels de méthodes plus petits. Décide de ce dont chaque appel a besoin et de ce qu’il renvoie avant de remplir tous les détails.

Planifie les étapes et les en-têtes

Un programme de suivi de l’exercice hebdomadaire lit 7 durées quotidiennes, en calcule le total et affiche un compte rendu. Ses méthodes auxiliaires peuvent être prévues ainsi :

  • readMinutes(Scanner scanner, int day) renvoie le nombre de minutes valide pour une journée.
  • isValidMinutes(int minutes) indique si l’entrée est comprise entre 0 et 1 440.
  • formatDuration(int minutes) renvoie un texte avec les heures entières et les minutes restantes.
  • averagePerDay(int total, int days) renvoie une moyenne de type double.
  • printSummary(int totalMinutes, int days) affiche le compte rendu.

Le même Scanner est transmis à chaque appel de lecture. Une méthode auxiliaire comme isValidMinutes n’a pas besoin de lire elle-même les données en entrée.

Utilise des bouchons pendant la construction

Un bouchon possède son en-tête définitif, mais un corps minimal temporaire, comme return 0;. Il permet au programme de compiler avant qu’une méthode auxiliaire soit implémentée. Remplace un bouchon, compile et vérifie cette méthode avant de remplacer le suivant. Un bouchon qui compile reste un travail inachevé ; sa réponse fixe ne peut pas vérifier un véritable calcul.

Voici le programme terminé :

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int total = 0;
        for (int day = 1; day <= 7; day++) {
            total += readMinutes(scanner, day);
        }
        printSummary(total, 7);
    }

    public static int readMinutes(Scanner scanner, int day) {
        System.out.println("Minutes for day " + day + ":");
        int minutes = scanner.nextInt();
        while (!isValidMinutes(minutes)) {
            System.out.println("Enter minutes from 0 to 1440:");
            minutes = scanner.nextInt();
        }
        return minutes;
    }

    public static boolean isValidMinutes(int minutes) {
        return minutes >= 0 && minutes <= 1440;
    }

    public static String formatDuration(int minutes) {
        return minutes / 60 + " h " + minutes % 60 + " min";
    }

    public static double averagePerDay(int total, int days) {
        return (double) total / days;
    }

    public static void printSummary(int totalMinutes, int days) {
        System.out.println("Total: " + formatDuration(totalMinutes));
        System.out.println("Daily average: "
            + averagePerDay(totalMinutes, days) + " min");
        if (totalMinutes >= 150) {
            System.out.println("Weekly goal reached");
        }
    }
}

Pour une entrée entière, readMinutes répète sa vérification de l’intervalle jusqu’à ce que le nombre soit valide. Avec les entrées quotidiennes 30, 45, 0, 60, 90, 45 et 45, le total est de 315. Le formatage donne « 5 h 15 min », la moyenne est de 45.0 minutes et le programme indique que son objectif hebdomadaire de 150 minutes est atteint.

Vérifie les petites méthodes et leurs bornes

Appelle chaque méthode de calcul avec des résultats connus. formatDuration(0) doit donner « 0 h 0 min », 59 donne « 0 h 59 min », 60 donne « 1 h 0 min » et 135 donne « 2 h 15 min ». Les entrées juste en dessous de 60 et égales à cette valeur vérifient le passage des minutes à une heure entière.

Pour isValidMinutes, teste -1, 0, 1440 et 1441. Les résultats attendus sont false, true, true et false. Afficher côte à côte les valeurs attendues et obtenues rend une erreur visible. JUnit automatise ce type de vérification.

Le développement ascendant commence par l’écriture et le test de petites méthodes auxiliaires, puis les réunit en étapes plus grandes. Tu peux planifier de manière descendante et construire de manière ascendante : établis d’abord la circulation des données, vérifie que les petits calculs fonctionnent, puis teste le programme une fois ses éléments reliés.

Points clés

  • La conception descendante transforme une tâche entière en appels, puis affine chaque tâche.
  • Décide des entrées et du type de retour de chaque méthode auxiliaire avant d’écrire son corps.
  • Un bouchon conserve un en-tête prévu alors que son corps est encore temporaire.
  • Teste des résultats connus et des valeurs situées aux bornes ou à proximité.
  • Construis et vérifie une méthode à la fois, puis teste le programme une fois ses éléments reliés.
  • Le développement ascendant construit de petites méthodes auxiliaires avant de les combiner.

Méthodes Java : exemples

5 Leçons Interactives

1

Construis une méthode réutilisable pour afficher une ligne

11 étapes
Définis une méthode auxiliaire, suis ses appels et ajoute des paramètres pour les entrées variables.
  1. 1
    IntroductionTransforme une action répétée en appel

    Un compte rendu nécessite un court séparateur à plusieurs endroits. Donner un nom de méthode à cette action permet au compte rendu de demander un séparateur sans répéter les instructions d’affichage. Cette action nommée est une méthode, et une seule définition sert à tous les appels.

    Commence par un séparateur fixe. Puis laisse le code appelant choisir sa largeur et son symbole à l’aide de paramètres. Suis la définition, l’appel et les valeurs fournies comme trois éléments distincts de la tâche.

  2. 2
    ExplicationLis un en-tête de méthode
    public static void printDivider() {
        System.out.println("====");
    }
    

    printDivider est le nom. public autorise les appels depuis d’autres classes ; static signifie qu’aucun objet n’est nécessaire. void indique qu’aucune valeur n’est renvoyée et () indique qu’aucune entrée n’est nécessaire.

    L’instruction entre les accolades constitue le corps. Rien ne s’affiche simplement parce que cette définition existe.

  3. 3
    ConseilPlace la méthode auxiliaire à côté de main

    Dans une classe classique, main et printDivider sont des méthodes distinctes à l’intérieur des mêmes accolades de classe. Ferme le corps de main avant de commencer l’en-tête de la méthode auxiliaire.

    Une méthode auxiliaire peut apparaître au-dessus ou au-dessous de main ; sa position ne détermine pas le moment de son exécution. Une définition placée dans main est rejetée. Vérifie d’abord les accolades lorsqu’un en-tête de méthode produit « illegal start of expression ».

  4. 4
    ExempleSuis le premier appel

    Supposons que main contienne :

    System.out.println("Items");
    printDivider();
    System.out.println("End");
    

    L’exécution affiche d’abord « Items ». L’appel entre dans printDivider, qui affiche « ==== ». Lorsque la méthode auxiliaire se termine, main reprend à son instruction suivante et affiche « End ».

    Le corps de la méthode auxiliaire s’exécute entre les deux instructions du code appelant, exactement à l’endroit où figure l’appel.

  5. 5
    DéfiPlace un second séparateur

    main appelle printDivider();, affiche "A", puis appelle à nouveau printDivider();. Quelles sont les trois lignes affichées ?

    ---reveal---

    Les lignes sont « ==== », « A » et « ==== ». Chaque appel entre dans le même corps de méthode auxiliaire, affiche une ligne et revient à son propre emplacement dans main.

    Écrire printDivider; ne constitue pas un appel. Même sans arguments, les parenthèses sont obligatoires.

  6. 6
    ExplicationFais de la largeur une entrée

    Remplace le corps fixe par une boucle :

    public static void printDivider(int length) {
        for (int i = 0; i < length; i++) {
            System.out.print("=");
        }
        System.out.println();
    }
    

    length est un paramètre déclaré dans l’en-tête. Dans printDivider(6);, l’argument 6 devient sa valeur initiale. Six passages dans la boucle affichent six symboles avant la fin de la ligne.

  7. 7
    ExempleÉvalue une expression avant l’appel
    int sections = 3;
    printDivider(sections + 2);
    

    Évalue d’abord sections + 2 pour obtenir 5. Entre ensuite dans la méthode auxiliaire avec son paramètre length = 5. Sa boucle affiche « ===== ».

    sections et length n’ont pas besoin de porter le même nom. Un paramètre reçoit la valeur de l’argument évalué ; le code appelant ne met pas le type dans l’appel.

  8. 8
    ExempleAjoute une seconde entrée variable

    Pour choisir aussi le symbole, utilise :

    public static void printDivider(int length, char symbol) {
        for (int i = 0; i < length; i++) {
            System.out.print(symbol);
        }
        System.out.println();
    }
    

    L’appel printDivider(3, '+'); transmet 3 à length et '+' à symbol, ce qui affiche « +++ ». Chaque paramètre doit avoir son propre type dans l’en-tête.

  9. 9
    ConseilVérifie le nombre, l’ordre et le type

    Un appel doit fournir une valeur compatible pour chaque paramètre. Il manque désormais le symbole dans printDivider(3);, tandis que printDivider("3", '+'); fournit du texte là où un int est nécessaire.

    Java peut effectuer une conversion élargissante d’un int en double pour un paramètre double. Il ne peut pas effectuer implicitement une conversion réductrice de 3.7 pour l’adapter à ce paramètre int. Le transtypage explicite (int) 3.7 fournit 3 en supprimant la partie fractionnaire.

  10. 10
    DéfiPrévois le résultat d’un appel paramétré

    Avec la méthode auxiliaire à deux paramètres, quelle ligne ce code affiche-t-il ?

    int width = 4;
    printDivider(width - 1, '#');
    

    ---reveal---

    Il affiche « ### ». L’expression est évaluée à 3, puis le premier paramètre reçoit ce nombre et le second reçoit '#'. La boucle s’exécute trois fois.

    L’appel est une instruction : il se termine donc par un point-virgule. Ses expressions d’arguments contiennent des valeurs, pas des déclarations de paramètres.

  11. 11
    RécapitulatifLis l’action et ses entrées

    Une définition donne un en-tête et un corps à une tâche ; un appel l’exécute, puis reprend dans le code appelant. Garde les définitions dans la classe et en dehors des autres méthodes.

    Les paramètres décrivent les entrées nécessaires. Les appels fournissent les arguments évalués dans l’ordre correspondant, avec le bon nombre et des types compatibles.

2

Renvoie des réponses et termine des recherches

13 étapes
Utilise les valeurs de retour dans le code appelant, puis suis les retours anticipés et les chemins de retour complets.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionRenvoie un résultat au code appelant
  2. 2
    ExplicationFais représenter une valeur par un appel
  3. 3
    Point cléUn affichage ne peut pas fournir une valeur à une affectation
  4. 4
    ExempleConserve la partie fractionnaire
  5. 5
    DéfiUtilise le résultat dans une autre expression
  6. 6
    ExempleRenvoie du texte formaté
  7. 7
    ExplicationUn return termine cet appel
  8. 8
    ConseilVérifie le chemin qui ne passe pas par le if
  9. 9
    ExempleÉcris une recherche avec un résultat d’échec
  10. 10
    ExempleSuis la recherche jusqu’à sa fin
  11. 11
    DéfiRepère un échec prématuré
  12. 12
    DéfiRelie un résultat de recherche à une condition
  13. 13
    RécapitulatifSuis la réponse et le point d’arrêt
3

Distingue les variables de chaque appel

15 étapes
Suis la portée, les valeurs copiées et les cadres de pile en attente dans un petit programme.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionAssocie chaque variable à son appel
  2. 2
    ExplicationUne méthode auxiliaire voit ses propres variables locales
  3. 3
    ExempleGarde une somme en dehors de la boucle
  4. 4
    DéfiDistingue la portée de l’initialisation
  5. 5
    ExempleCopie un nombre dans un paramètre
  6. 6
    ExempleAffecte la nouvelle valeur renvoyée
  7. 7
    DéfiPrévois le résultat d’un second appel
  8. 8
    LienLes références copiées suivent la même règle
  9. 9
    ExempleCommence un calcul externe
  10. 10
    ExempleMets le code appelant en pause et empile un autre cadre
  11. 11
    ExempleTransmets les résultats vers le bas de la pile
  12. 12
    ConseilLis une erreur à partir du cadre supérieur
  13. 13
    DéfiRepère le travail en attente
  14. 14
    DéfiRelie les copies aux résultats dans la pile
  15. 15
    RécapitulatifDistingue les noms, les valeurs et les cadres
4

Choisis la bonne méthode surchargée

12 étapes
Compare les signatures, réutilise une surcharge plus longue et détermine la méthode appelée à partir des types des arguments.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionUne tâche, plusieurs formes d’entrée
  2. 2
    ExplicationIdentifie une signature
  3. 3
    Point cléUn type de retour ne peut pas créer une surcharge
  4. 4
    ExempleDélègue à la version complète
  5. 5
    DéfiVérifie une troisième déclaration proposée
  6. 6
    ExplicationChoisis une correspondance numérique exacte
  7. 7
    ExempleUtilise la conversion élargissante sans conversion réductrice
  8. 8
    ExempleDistingue l’appel de son affectation
  9. 9
    ExempleCompare chaque position d’argument
  10. 10
    ConseilUtilise la liste des méthodes candidates pour diagnostiquer un appel
  11. 11
    DéfiChoisis une version, puis utilise son résultat
  12. 12
    RécapitulatifVérifie les définitions avant les appels
5

Construis un petit compte rendu à partir de méthodes auxiliaires testées

16 étapes
Sépare les tâches, extrais le code répété et planifie un programme complet autour de méthodes testées.

Enregistre cette unité pour suivre chaque Leçon Interactive pas à pas.

  1. 1
    IntroductionTransforme un compte rendu en petites tâches
  2. 2
    ExplicationNomme la tâche avant d’écrire le corps
  3. 3
    ExempleRends le calcul réutilisable
  4. 4
    ExempleDonne à l’affichage sa propre méthode
  5. 5
    DéfiRéutilise un calcul sans compte rendu
  6. 6
    ExplicationRepère ce qui change dans le code répété
  7. 7
    ExempleChoisis l’en-tête extrait
  8. 8
    ExemplePlace la boucle commune à un seul endroit
  9. 9
    DéfiPréserve la dernière répétition
  10. 10
    ExplicationPlanifie le programme de manière descendante
  11. 11
    ConseilUtilise un bouchon uniquement pendant la construction
  12. 12
    ExempleTransmets le même lecteur d’entrée
  13. 13
    ExempleVérifie le calcul avant de le relier au reste
  14. 14
    ExempleVérifie une séquence d’entrées dans le programme assemblé
  15. 15
    DéfiRepère une erreur de liaison
  16. 16
    RécapitulatifConstruis des éléments utiles et relie-les

Méthodes Java : QCM

40 Questions Pratiques en 4 séries

Série 1 : Appels, valeurs et petites étapes d’un programme10 Questions Pratiques

Question 1 sur 10

Une classe Java classique possède une méthode main et a besoin d’une nouvelle méthode printMenu. Où faut-il placer cette nouvelle définition ?
  1. Dans main, après sa dernière instruction.
  2. Dans la classe, hors de toute autre méthode.
  3. Hors de la classe, après son accolade fermante.
  4. Dans la méthode qui doit l’appeler.
Afficher la réponseMasquer la réponse
Réponse : B
Une définition de méthode doit se trouver dans la classe et en dehors de toute autre méthode. Appeler une méthode auxiliaire depuis main ne fait pas de sa définition une partie de main ; la placer à cet endroit créerait une définition de méthode imbriquée, que Java rejette.

Question 2 sur 10

Quelle ligne cet appel affiche-t-il ?

public static void showPair(int rows, int columns) {
    System.out.println(rows + ":" + columns);
}
int width = 7;
showPair(3, width - 2);
  1. 5:3
  2. 3:7
  3. 7:3
  4. 3:5
Afficher la réponseMasquer la réponse
Réponse : D
Le premier argument fournit rows = 3. L’expression width - 2 est évaluée avant l’appel : le second paramètre reçoit donc 5 et la sortie est « 3:5 ». Le nom width dans le code appelant ne change pas la correspondance des arguments par position.

Question 3 sur 10

Quelle valeur halfTotal(8, 5) renvoie-t-elle ?

public static double halfTotal(int a, int b) {
    return (a + b) / 2;
}
  1. 6.0
  2. 6.5
  3. 13.0
  4. 7.0
Afficher la réponseMasquer la réponse
Réponse : A
L’addition produit le int 13, et la division par le int 2 produit 6. Ce résultat subit une conversion élargissante en double pour renvoyer 6.0. Un type de retour double ne fait pas utiliser de décimales à la division précédente ; il faudrait un diviseur 2.0 pour obtenir 6.5.

Question 4 sur 10

Pourquoi cette méthode ne compile-t-elle pas ?

public static String label(int n) {
    if (n >= 0) {
        return "ready";
    }
}
  1. La valeur de retour doit d’abord être affichée.
  2. La comparaison ne peut pas figurer dans une méthode.
  3. Les entrées négatives atteignent la fin sans valeur.
  4. Les méthodes String ne peuvent pas renvoyer de valeur dans un if.
Afficher la réponseMasquer la réponse
Réponse : C
Une entrée négative ignore le corps du if et atteint l’accolade fermante sans résultat String. Une méthode ayant ce type de retour doit aussi renvoyer une valeur pour ce chemin. Renvoyer une valeur depuis un if est valide ; c’est l’absence de réponse hors de cette branche qui cause l’erreur.

Question 5 sur 10

Une boucle doit additionner les entiers de 2 à 4 et afficher ensuite le total. Quelle déclaration doit remplacer le commentaire ?

// declaration here
for (int i = 2; i <= 4; i++) {
    total += i;
}
System.out.println(total);
  1. int total;
  2. int total = 0;
  3. int total = 2;
  4. int total = i;
Afficher la réponseMasquer la réponse
Réponse : B
Initialise total à 0 avant la boucle afin que les trois additions mettent à jour la même variable et qu’elle reste visible pour l’affichage final. Déclarer seulement int total; n’affecte pas de valeur initiale : total += i lirait donc une variable locale non initialisée.

Question 6 sur 10

Quels sont les deux nombres affichés, dans l’ordre ?

public static void lower(int level) {
    level -= 3;
    System.out.println(level);
}
int level = 14;
lower(level);
System.out.println(level);
  1. 11, puis 14
  2. 11, puis 11
  3. 14, puis 11
  4. 14, puis 14
Afficher la réponseMasquer la réponse
Réponse : A
La méthode auxiliaire reçoit son propre level initialisé à 14, ramène cette copie à 11 et l’affiche. Le level du code appelant reste à 14 et s’affiche ensuite. Utiliser le même nom dans les deux méthodes ne fait pas en sorte que l’affectation au paramètre mette à jour la variable du code appelant.

Question 7 sur 10

Une classe déclare déjà public static int scale(int value). Quel en-tête supplémentaire entrerait en conflit avec sa signature ?
  1. public static int scale(int value, int factor)
  2. public static double scale(double value)
  3. public static long scale(long value)
  4. public static double scale(int amount)
Afficher la réponseMasquer la réponse
Réponse : D
L’en-tête supplémentaire avec un paramètre int possède toujours la signature scale(int). Son type de retour double et le nom modifié du paramètre ne le distinguent pas de la méthode existante. Changer le type du paramètre ou ajouter un paramètre créerait une signature différente.

Question 8 sur 10

Une classe possède show(int n) et show(double n). Quelle méthode s’exécute pour show(12.0) ?
  1. show(int), avec 12
  2. Les deux, avec 12.0
  3. show(double), avec 12.0
  4. Aucune ; l’appel est ambigu
Afficher la réponseMasquer la réponse
Réponse : C
Le littéral 12.0 est de type double : la surcharge double est donc une correspondance exacte. Sa valeur entière ne fait pas de l’expression un int. La surcharge int nécessiterait une conversion réductrice que Java n’effectue pas implicitement pour cet argument.

Question 9 sur 10

Un programme d’itinéraires doit calculer une vitesse moyenne et afficher un compte rendu. Quelle décomposition rend le calcul de vitesse réutilisable dans un programme qui compare des itinéraires ?
  1. Calculer et renvoyer la vitesse ; l’afficher dans une méthode distincte.
  2. Calculer et afficher la vitesse ; ne renvoyer aucune valeur de la méthode.
  3. Lire et afficher la vitesse ; la recalculer dans chaque code appelant.
  4. Calculer et afficher la vitesse ; renvoyer le titre du compte rendu.
Afficher la réponseMasquer la réponse
Réponse : A
Une méthode qui reçoit une distance et une durée et renvoie une vitesse peut servir à un compte rendu comme à une comparaison. Place l’affichage dans une autre méthode. Une méthode de calcul void qui ne fait qu’afficher sa réponse ne fournit pas de résultat numérique utilisable au code de comparaison.

Question 10 sur 10

Un programme doit accepter des durées de tâches allant de 0 à 90 minutes et indiquer leur moyenne. Il utilise actuellement ces méthodes auxiliaires. Quels deux appels peuvent révéler les deux défauts indépendants ?

public static boolean valid(int m) {
    return m > 0 && m <= 90;
}
public static double mean(int total, int count) {
    return total / count;
}
  1. valid(45) et mean(8, 2)
  2. valid(0) et mean(7, 2)
  3. valid(91) et mean(8, 2)
  4. valid(90) et mean(7, 2)
Afficher la réponseMasquer la réponse
Réponse : B
valid(0) renvoie à tort false alors que zéro est autorisé. mean(7, 2) renvoie 3.0 au lieu de 3.5 parce que la division entière a lieu avant la conversion élargissante. Tester valid(90) et cette moyenne ne révèle que le défaut de division, puisque la borne supérieure fonctionne déjà.
Série 2 : Suis les méthodes auxiliaires et corrige leur découpage10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Quelle suite de lignes est affichée ?

public static void frame() {
    System.out.println("Open");
    mark();
    System.out.println("Close");
}
public static void mark() {
    System.out.println("Mark");
}

main appelle frame();, puis affiche "Done".

  1. « Open », « Close », « Mark », « Done »
  2. « Mark », « Open », « Close », « Done »
  3. « Open », « Mark », « Done », « Close »
  4. « Open », « Mark », « Close », « Done »
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Une méthode possède l’en-tête public static void repeat(int count). Quelle valeur est transmise à count dans repeat((int) 3.9 + 2); ?
  1. 3
  2. 5
  3. 6
  4. 5.9
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Quelle valeur est affectée à result ?

public static int addTwo(int n) {
    return n + 2;
}
public static int product(int a, int b) {
    return a * b;
}
int result = product(addTwo(4), addTwo(addTwo(1)));
  1. 24
  2. 42
  3. 30
  4. 18
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

La méthode doit renvoyer la première valeur paire d’un intervalle dont les bornes sont incluses, ou -1 s’il n’en existe aucune. Elle renvoie à tort -1 pour (9, 12). Quelle modification corrige la recherche ?

public static int firstEven(int start, int end) {
    for (int n = start; n <= end; n++) {
        if (n % 2 == 0) {
            return n;
        } else {
            return -1;
        }
    }
    return -1;
}
  1. Supprimer la branche else et garder le return final.
  2. Remplacer le return du else par return n + 1;.
  3. Déplacer le return final dans la boucle après le if/else.
  4. Remplacer le test du if par n % 2 != 0.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Une méthode auxiliaire a besoin du nombre contenu dans la variable locale pages de main. Comment les données doivent-elles parvenir à la méthode auxiliaire ?
  1. Déclarer un autre pages non initialisé dans la méthode auxiliaire.
  2. Déplacer la méthode auxiliaire sous main dans la classe.
  3. Placer simplement l’appel dans la portée de pages.
  4. Ajouter un paramètre et transmettre pages comme argument.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Quelle valeur outer(4) renvoie-t-elle à main ?

public static int outer(int n) {
    int saved = n;
    int changed = inner(n + 1);
    return saved + changed;
}
public static int inner(int n) {
    n *= 2;
    return n - 1;
}
  1. 14
  2. 13
  3. 19
  4. 9
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Une méthode à deux arguments printBorder(int length, char symbol) contient déjà la boucle d’affichage. Comment printBorder(int length) doit-elle fournir '#' par défaut sans dupliquer la boucle ?
  1. Appeler printBorder(length, '#'); dans son corps.
  2. Ajouter char symbol = '#' comme paramètre par défaut dans l’en-tête.
  3. Appeler printBorder('#', length); dans son corps.
  4. Appeler printBorder(length); dans son corps.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Ces surcharges appartiennent à une même classe. Quelle valeur est stockée dans answer ?

public static int adjust(int n) { return n + 1; }
public static double adjust(double n) { return n + 0.5; }
double answer = adjust(6);
  1. 6.5
  2. 6.0
  3. 7.5
  4. 7.0
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Deux blocs de code calculent des aires de rectangles, l’un avec 8 * 3 et l’autre avec 11 * 4. Les deux résultats sont nécessaires pour des comparaisons ultérieures. Quel en-tête de méthode auxiliaire convient pour extraire ce calcul commun ?
  1. public static void area(int width, int height)
  2. public static int area(int width)
  3. public static int area(int width, int height)
  4. public static int area()
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Pourquoi public static int countItems(int limit) { return 0; } est-il un bouchon temporaire utile ?
  1. Il prouve que tous les nombres d’éléments sont corrects.
  2. Il évite de devoir tester la méthode terminée.
  3. Il permet aux appels de compiler avant que le corps réel soit prêt.
  4. Il fournit à Java une valeur de paramètre par défaut.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 3 : Relie les arguments, les chemins de retour et la conception10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Un programmeur écrit ceci dans une classe. Pourquoi la définition de la méthode auxiliaire est-elle rejetée ?

public static void main(String[] args) {
    public static void printTitle() {
        System.out.println("Schedule");
    }
}
  1. Une méthode auxiliaire doit être placée au-dessus de main.
  2. Une méthode d’affichage doit renvoyer un String.
  3. La méthode auxiliaire est définie dans une autre méthode.
  4. Le nom de la méthode auxiliaire doit commencer par une majuscule.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

La méthode renvoie le nombre de groupes entiers. Que renvoie groups(5, 18) ?

public static int groups(int groupSize, int items) {
    return items / groupSize;
}
  1. 3
  2. 0
  3. 3.6
  4. 4
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Une méthode auxiliaire de calendrier est écrite comme ci-dessous. Quelle paire de résultats est renvoyée par leap(2100), puis par leap(2400) ?

public static boolean leap(int year) {
    return (year % 4 == 0 && year % 100 != 0)
        || year % 400 == 0;
}
  1. true, puis true
  2. false, puis true
  3. false, puis false
  4. true, puis false
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Quel texte est affiché par le code appelant ?

public static void tag(String name) {
    name = name + "-checked";
}
String label = "parcel";
tag(label);
System.out.println(label);
  1. « parcel-checked »
  2. « checked »
  3. « parcelparcel »
  4. « parcel »
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Un rapport d’erreur commence par ArithmeticException: / by zero et les cadres suivants. Où la division qui a échoué a-t-elle eu lieu ?

at Main.unitCount(Main.java:23)
at Main.printLoad(Main.java:15)
at Main.main(Main.java:5)
  1. Dans main, à la ligne 5.
  2. Dans printLoad, à la ligne 15.
  3. Dans unitCount, à la ligne 23.
  4. Après le retour de unitCount à la ligne 15.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Une classe déclare public static void describe(String name, int count). Quel en-tête ajoute une surcharge valide en changeant l’ordre des types de paramètres ?
  1. public static int describe(String name, int count)
  2. public static void describe(int count, String name)
  3. public static void describe(String title, int number)
  4. private static void describe(String name, int count)
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Quelle ligne est affichée par cet appel ? Le caractère 'B' a la valeur numérique 66.

public static int code(int n) { return n + 1; }
public static String code(String s) { return s + "!"; }
double result = code('B');
System.out.println(result);
  1. 67.0
  2. 66.0
  3. « B! »
  4. 67
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Une méthode auxiliaire ne doit pouvoir être appelée que par du code de la même classe. Quel modificateur d’accès son en-tête statique doit-il utiliser ?
  1. public
  2. static
  3. void
  4. private
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Le programme initial affiche les totaux 20 et 30, dans cet ordre. Après extraction, il utilise cette méthode auxiliaire. Comment faut-il écrire les deux appels pour conserver ces totaux ?

public static int sumMultiples(int factor, int count) {
    int total = 0;
    for (int i = 1; i <= count; i++) {
        total += factor * i;
    }
    return total;
}

La première boucle initiale additionnait 2, 4, 6 et 8. La seconde additionnait 5, 10 et 15.

  1. sumMultiples(2, 4) puis sumMultiples(5, 3)
  2. sumMultiples(4, 2) puis sumMultiples(3, 5)
  3. sumMultiples(2, 8) puis sumMultiples(5, 15)
  4. sumMultiples(2, 3) puis sumMultiples(5, 2)
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Un programme lit cinq nombres quotidiens, en calcule le total et affiche une moyenne. Les en-têtes prévus pour les méthodes auxiliaires figurent ci-dessous. Quelle liaison dans main permet à l’étape de compte rendu de recevoir toutes les données nécessaires ?

public static int readCount(Scanner scanner, int day)
public static double average(int total, int days)
public static void printReport(int total, int days)

Le Scanner est déjà créé.

  1. Écraser un seul count dans la boucle ; appeler printReport(count, 5).
  2. Cumuler les cinq nombres renvoyés ; appeler printReport(total, 5).
  3. Afficher chaque nombre renvoyé ; appeler ensuite printReport(0, 5).
  4. Additionner les numéros des jours dans la boucle ; appeler printReport(total, 5).
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Série 4 : Diagnostique des interactions complètes entre méthodes10 Questions Pratiques

Enregistre cette unité pour voir chaque réponse et t'entraîner sur chaque série.

Question 1 sur 10

Quelle ligne est affichée ?

public static int next(int n) { return n + 1; }
public static double half(int n) { return n / 2.0; }
int n = 5;
next(n);
double result = half(next(n)) + n;
System.out.println(result);
  1. 9.5
  2. 7.5
  3. 3.0
  4. 8.0
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 2 sur 10

Quelle valeur locate(5) renvoie-t-elle ?

public static int locate(int limit) {
    int total = 0;
    for (int n = 1; n <= limit; n++) {
        total += n;
        if (total > 8) {
            return n;
        }
    }
    return -1;
}
  1. 4
  2. 5
  3. 10
  4. 15
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 3 sur 10

Le code doit additionner les poids et afficher leur somme après la boucle. Il ne compile pas actuellement. Quelle modification corrige le problème de portée tout en conservant une somme cumulée ?

for (int box = 1; box <= 3; box++) {
    int total = 0;
    total += box * 2;
}
System.out.println(total);
  1. Déplacer uniquement println(total) dans la boucle.
  2. Déclarer int total; avant la boucle et supprimer sa déclaration interne.
  3. Déplacer int total = 0; avant la boucle et supprimer sa déclaration interne.
  4. Déclarer int total = 0; après la boucle, avant l’affichage.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 4 sur 10

Quelle paire de valeurs est affichée sous la forme a:b ?

public static int shift(int n) {
    n += 4;
    return n;
}
int a = 2;
int b = shift(a);
a = shift(b);
System.out.println(a + ":" + b);
  1. 6:10
  2. 10:6
  3. 10:10
  4. 6:6
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 5 sur 10

Au point indiqué, quelles sont les valeurs des deux variables locales nommées saved, en lisant d’abord le cadre externe, puis le cadre interne ?

public static int outer(int n) {
    int saved = n + 2;
    return inner(saved) + saved;
}
public static int inner(int n) {
    int saved = n * 3;
    // program pauses here
    return saved;
}

main a appelé outer(5).

  1. 7 et 21
  2. 21 et 21
  3. 5 et 15
  4. 7 et 7
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 6 sur 10

Un programme continue de démarrer de nouveaux appels sans laisser les appels existants se terminer. Quelle erreur peut se produire lorsqu’il ne reste plus d’espace dans la pile ?
  1. ArithmeticException
  2. « missing return statement »
  3. « cannot find symbol »
  4. StackOverflowError
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 7 sur 10

Les méthodes ci-dessous sont déclarées dans une même classe. Que se passe-t-il pour double result = merge(4, 9); ?

public static int merge(int a, double b) { return a; }
public static double merge(double a, int b) { return b; }
public static double merge(double a, double b) { return a + b; }
  1. La destination double sélectionne (double, int) et stocke 9.0.
  2. L’appel est ambigu entre les deux versions de types mixtes.
  3. Le premier argument int sélectionne (int, double) et stocke 4.0.
  4. La version entièrement double est sélectionnée et stocke 13.0.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 8 sur 10

Un calcul de capteur est utile, mais sa méthode actuelle affiche aussi un long message d’état. Un second code appelant a besoin du nombre sans ce message. Quelle conception permet aux deux codes appelants de partager une méthode de calcul et de choisir leur propre affichage ?
  1. Ajouter une seconde copie du calcul sans l’affichage.
  2. Renommer la méthode existante pour décrire les deux actions.
  3. Renvoyer le nombre et déplacer l’affichage dans le code appelant qui produit le compte rendu.
  4. Rendre la méthode combinée publique pour que les deux codes appelants puissent l’utiliser.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 9 sur 10

Deux blocs affichent un libellé suivi d’une ligne par élément. Le premier affiche "Crate" avec des éléments numérotés de 1 à 2 ; le second affiche "Bag" avec des éléments numérotés de 1 à 4. Quel corps extrait préserve ce format pour printItems(String label, int count) ?
  1. Afficher label dans une boucle partant de 0 tant que i < count ; n’afficher aucun numéro.
  2. Afficher label une fois ; parcourir une boucle depuis 1 tant que i < count et afficher i.
  3. Afficher label une fois ; parcourir une boucle depuis 0 tant que i <= count et afficher i.
  4. Afficher label une fois ; parcourir une boucle depuis 1 tant que i <= count et afficher i.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Question 10 sur 10

Une méthode auxiliaire doit renvoyer une moyenne quotidienne décimale :

public static double dailyAverage(int total, int days) {
    return total / days;
}

Pourquoi vérifier uniquement (24, 6) ne permet-il pas de révéler son défaut de calcul ?

  1. Cette division est exacte, donc la troncature ne fait perdre aucune partie fractionnaire.
  2. La méthode convertit les deux opérandes int par élargissement avant la division.
  3. Cette entrée teste un quotient dont la partie fractionnaire est non nulle.
  4. Le résultat est ensuite arrondi à l’entier le plus proche.
Afficher la réponseMasquer la réponse

Enregistre cette unité pour voir cette réponse.

Tu bloques sur ton propre exercice ? Aide aux Devoirs

Mots-Clés

51 Mots-Clés, chacun avec sa définition

A

Accumulateur
Un accumulateur est une variable qui conserve un résultat cumulé pendant qu’une boucle y combine des valeurs successives.
Déclare sum avant une boucle pour que chaque itération ajoute une valeur à la somme conservée depuis le passage précédent.
Appel ambigu
Un appel ambigu convient à plusieurs surcharges sans qu’une seule soit la plus spécifique ; le compilateur ne peut donc pas en sélectionner une.
Les paires (int, double) et (double, int) rendent ambigu un appel avec deux arguments int.
Appel de méthode
Un appel de méthode est une expression qui nomme une méthode et fournit ses arguments entre parenthèses pour invoquer son corps.
L’instruction printHeader(); exécute la méthode d’affichage de l’en-tête à cet endroit du code appelant.
Appel imbriqué
Un appel imbriqué est un appel de méthode utilisé dans un autre appel, de sorte que son résultat doit être obtenu avant l’exécution de la méthode externe.
Dans Math.max(sum(2, 6), 5), le résultat 8 devient le premier argument de Math.max.
Argument
Un argument est une expression fournie dans un appel de méthode, dont la valeur évaluée est transmise au paramètre correspondant.
Dans printRepeated("go", 4), les arguments fournissent le texte et le nombre de répétitions.

B

Bloc
Un bloc est un groupe d’instructions entouré d’accolades qui peut former un corps de méthode, un corps de boucle ou une branche conditionnelle.
Déclarer un compteur dans un bloc if limite ce nom local à la zone située avant l’accolade fermante du bloc.
Bouchon
Un bouchon est une méthode temporaire avec son en-tête prévu et un corps minimal, qui permet au code environnant inachevé de compiler.
Un return 0; temporaire peut servir de remplacement pendant que le calcul réel est implémenté et vérifié.

C

Cadre de pile
Un cadre de pile contient les paramètres et les variables locales d’un appel, ainsi que l’information indiquant où le code appelant doit reprendre ensuite.
Deux appels peuvent chacun posséder un paramètre nommé minutes, car les paramètres occupent des cadres distincts.
Cas limite
Un cas limite teste une entrée située à une borne ou à proximité, là où le comportement attendu d’une méthode change, afin de révéler des erreurs aux bornes.
Pour un intervalle valide de 0 à 1 440, vérifie -1, 0, 1440 et 1441 comme entrées distinctes.
Chaîne de caractères immuable
Une chaîne String immuable est une chaîne dont le contenu ne peut pas changer après sa création ; des opérations sur le texte peuvent produire un autre String.
Concaténer "!" et affecter le résultat à un paramètre String laisse inchangée la référence du code appelant.
Code dupliqué
Le code dupliqué répète des instructions identiques ou presque identiques, ce qui laisse plusieurs endroits à mettre à jour lorsque la tâche commune change.
Deux boucles de sommation avec des bornes supérieures différentes peuvent souvent être remplacées par une méthode auxiliaire et deux appels.
Conception descendante
La conception descendante commence par le problème entier et décompose progressivement ses étapes en tâches nommées plus petites ou en appels de méthodes.
Planifie les appels de lecture, de calcul et de compte rendu dans main avant de remplir les corps des méthodes auxiliaires.
Conversion élargissante
Une conversion élargissante transforme une valeur en un type plus large autorisé, ce qui permet à un argument int de correspondre à un paramètre double.
Transmettre 12 à un paramètre double lui donne la valeur 12.0 sans nécessiter de transtypage explicite.
Conversion réductrice
Une conversion réductrice transforme une valeur numérique en un type plus restreint et peut entraîner une perte d’information ; les appels de méthodes ne l’effectuent pas implicitement.
Transmettre 9.0 à un paramètre int échoue sans transtypage, même si la valeur n’a pas de partie fractionnaire.
Corps de méthode
Un corps de méthode est le bloc entouré d’accolades qui contient les instructions exécutées lorsque la méthode est appelée.
L’appel entre dans le corps, en exécute les instructions, puis l’exécution reprend dans le code appelant en attente.
Correspondance exacte
Une correspondance exacte se produit lorsque les types des arguments correspondent déjà aux types des paramètres d’une méthode sans conversion.
Avec show(int) et show(double), show(9) correspond exactement à la version int.

D

Débordement de pile
Un débordement de pile se produit lorsqu’une chaîne d’appels de méthodes nécessite plus d’espace de pile qu’il n’en existe, ce qui produit une StackOverflowError.
Des appels qui continuent d’ajouter des cadres sans les laisser se terminer peuvent finir par épuiser la pile.
Décomposition
La décomposition divise le problème d’un programme en tâches plus petites et utiles, qui peuvent chacune être implémentées sous forme d’une méthode ciblée.
Un compte rendu de sortie peut séparer l’obtention des données en entrée, le calcul d’une vitesse et l’affichage du résultat.
Dernier entré, premier sorti
Dernier entré, premier sorti désigne l’ordre de la pile dans lequel l’appel inachevé le plus récent se termine avant la reprise du code appelant en attente.
Une méthode auxiliaire interne se termine avant que la méthode auxiliaire externe puisse finir d’utiliser la valeur renvoyée.
Développement ascendant
Le développement ascendant construit et teste d’abord de petites méthodes, puis les combine en étapes plus grandes du programme.
Teste séparément une vérification de validité et une méthode de formatage avant de les utiliser dans un programme complet de compte rendu.
Développement incrémental
Le développement incrémental ajoute et vérifie un petit morceau de code fonctionnel à la fois, ce qui rend la cause d’une nouvelle erreur plus facile à trouver.
Implémente une méthode auxiliaire, compile-la, teste des résultats connus, puis relie-la à la partie suivante.

E

En-tête de méthode
Un en-tête de méthode déclare le nom, les modificateurs, le type de retour et les paramètres d’une méthode avant le début de son corps.
L’en-tête public static void greet() décrit une action appelable sans entrée ni valeur de retour.
Extraction de méthode
L’extraction de méthode déplace un morceau de code cohérent dans une méthode auxiliaire, en transformant les entrées variables en paramètres et les résultats nécessaires en valeurs de retour.
Extraire une boucle de sommation dans sumUpTo(int n) laisse au code appelant la responsabilité de son propre texte de compte rendu.

I

Initialisation
L’initialisation donne à une variable sa valeur initiale avant que le code suivant la lise ou la mette à jour ; les variables locales ne reçoivent pas automatiquement de valeur initiale.
Écrire int total = 0; avant une boucle de sommation donne à la première addition une somme existante à mettre à jour.
Instruction inaccessible
Une instruction inaccessible est du code que Java détermine impossible à exécuter, comme une instruction placée directement après return dans le même bloc.
Une instruction d’affichage placée directement après un return inconditionnel dans le même bloc est rejetée par le compilateur.
Instruction return
Une instruction return termine l’appel de méthode en cours, en renvoyant une valeur pour une méthode non void ou aucune valeur pour une méthode void.
L’instruction return minutes * 60; termine le calcul et fournit le nombre de secondes.

J

Javadoc
Javadoc est une documentation écrite dans un commentaire /** ... */ au-dessus d’une déclaration, avec des balises qui décrivent les paramètres et les résultats.
Utilise @param minutes pour expliquer une entrée et @return pour décrire le texte formaté produit.

L

Liste des paramètres
Une liste des paramètres est la suite ordonnée des variables d’entrée typées entre les parenthèses d’un en-tête de méthode.
La liste (int width, int height) exige deux arguments, associés d’abord à width, puis à height.

M

Méthode
Une méthode est un bloc d’instructions nommé qui accomplit une tâche et s’exécute chaque fois que l’exécution du programme atteint un appel à cette méthode.
Une méthode printHeader() peut afficher le même titre de compte rendu à plusieurs endroits d’un programme.
Méthode auxiliaire
Une méthode auxiliaire accomplit une tâche plus petite utilisée par une autre méthode, ce qui rend l’opération globale plus facile à lire et à construire.
Une méthode de compte rendu peut appeler une méthode de formatage de durée au lieu d’effectuer elle-même le formatage.
Méthode booléenne
Une méthode booléenne renvoie true ou false, souvent pour répondre à une question dont le code appelant utilise directement la réponse comme condition.
Un appel comme isEven(count) peut être placé directement entre les parenthèses d’une instruction if.
Méthode privée
Une méthode privée ne peut être appelée que par du code de sa propre classe, ce qui rend une méthode auxiliaire interne inaccessible aux autres classes.
Déclarer un calcul private static permet à sa propre classe de l’utiliser sans offrir d’appel externe.
Méthode statique
Une méthode statique appartient à une classe et peut être appelée sans créer d’objet de cette classe.
L’appel statique Math.abs(-6) utilise le nom de classe Math et renvoie la valeur positive 6.

P

Paramètre
Un paramètre est une variable typée déclarée dans l’en-tête d’une méthode, qui reçoit une valeur au début d’un appel donné.
Dans printRepeated(String text, int times), text et times sont les deux paramètres déclarés.
Passage par valeur
Le passage par valeur signifie que chaque paramètre reçoit une copie de la valeur de son argument : réaffecter le paramètre laisse donc inchangée la variable du code appelant.
Une méthode auxiliaire peut augmenter son paramètre int tandis que le int initial du code appelant reste inchangé.
Pile d’appels
La pile d’appels enregistre les appels de méthodes inachevés : l’appel le plus récent s’exécute au sommet tandis que les codes qui l’ont appelé attendent en dessous.
Lorsque main appelle une méthode auxiliaire qui en appelle une autre, trois cadres peuvent se trouver simultanément dans la pile.
Portée
La portée d’une variable est la zone du texte du programme où son nom peut légalement être utilisé pour désigner cette variable.
Un compteur déclaré dans un en-tête for est dans sa portée dans cette boucle, mais ne peut pas être lu après celle-ci.

R

Refactorisation
La refactorisation modifie la structure du code tout en préservant son comportement, par exemple en remplaçant des calculs répétés par des appels.
Compare les mêmes entrées avant et après l’extraction pour vérifier que les résultats et les sorties restent identiques.
Référence
Une référence est une valeur qui désigne un objet ; copier cette valeur peut permettre à deux variables de faire référence au même objet.
Transmettre un String copie sa référence dans le paramètre sans lier les affectations aux deux variables.
Résolution de surcharge
La résolution de surcharge est le processus par lequel le compilateur sélectionne une version de méthode appropriée à partir du nombre et des types des arguments d’un appel.
Un argument int sélectionne une surcharge int exacte avant une version qui nécessiterait une conversion.
Retour anticipé
Un retour anticipé termine une méthode avant la fin de son corps, souvent après la découverte d’une correspondance ou le traitement d’une condition sur une entrée.
Une recherche s’arrête dès que return candidate; s’exécute, même s’il reste des candidats dans la boucle.

S

Signature de méthode
Pour ces méthodes, une signature de méthode est composée du nom et des types des paramètres dans leur ordre ; les types de retour et les noms des paramètres ne la distinguent pas.
Remplacer width par w laisse area(int, int) inchangé et ne peut pas créer une nouvelle surcharge.
Surcharge
La surcharge consiste à définir des méthodes de même nom avec des listes de paramètres différentes afin qu’une opération accepte différentes formes d’entrée.
Deux méthodes nommées max peuvent accepter deux int et trois int tout en conservant un seul sens pour ce nom.
Surcharge par délégation
Une surcharge par délégation appelle une autre version de la même opération, souvent en fournissant une valeur fixe pour un argument omis.
Une méthode d’affichage de ligne à un argument peut appeler la version à deux arguments avec un tiret comme caractère fixe.

T

Trace de pile
Une trace de pile est une liste affichée des cadres d’appels actifs lors d’une erreur, qui indique les noms des méthodes et les emplacements dans la chaîne d’appels.
Le premier cadre situe l’erreur et les lignes suivantes montrent quelles méthodes ont conduit à cet appel.
Transtypage
Un transtypage est une conversion de type explicite écrite avec un type cible entre parenthèses avant l’expression à convertir.
L’expression (int) 4.9 fournit 4 à un paramètre int en supprimant la partie fractionnaire.
Type de retour
Un type de retour précise le type de valeur qu’une méthode fournit au code appelant ; void déclare qu’elle ne fournit aucune valeur.
Une méthode déclarée double average(int a, int b) promet un résultat double au code appelant.

V

Valeur de retour
Une valeur de retour est le résultat qu’une méthode renvoie à l’endroit de l’appel, où il peut être stocké ou utilisé dans une autre expression.
Après int total = sum(6, 8);, la valeur 14 renvoyée est stockée dans la variable total du code appelant.
Valeur sentinelle
Une valeur sentinelle est un résultat particulier convenu, utilisé pour signaler une situation comme une recherche qui ne trouve aucun candidat correspondant.
Renvoyer -1 après une recherche peut signaler « non trouvé » lorsque -1 ne peut pas être une correspondance valide.
Variable locale
Une variable locale est déclarée dans une méthode ou un bloc et appartient à l’exécution de cette zone, pas au programme entier.
Le total local d’une méthode auxiliaire est distinct de la variable locale d’une autre méthode également nommée total.
void
Le mot-clé Java void déclare qu’une méthode ne renvoie aucune valeur, même si son corps effectue des actions comme un affichage.
Un appel void à printTotal ne peut pas fournir le membre droit d’une affectation à un int simplement parce qu’il affiche un nombre.

À propos de cette unité

Par StudeliSignaler une erreur

Crée ton propre Matériel d'Étude

Transforme tes notes, diapos et documents en Guides d'Étude, Questions Pratiques, Flashcards et 6 autres outils.

Commencer