INF1563 Programmation I
Méthodes
Algorithme paramétré
Muffins aux bananes
- ingrédients : cassonade, huile, oeuf, bananes, farine, ...
- algorithme
- Faire chauffer le four à 375f
- Mélanger l'oeuf avec la cassonade, l'huile, la mélasse et les bananes
- Ajouter le gruau, le son de blé, la farine, ...
- Ajouter le lait en dernier
- Bien mélanger et mettre dans les moules à muffin
- Cuire environ 25 min à 375f
Muffins aux dates
- simple ! Il suffit de remplacer les bananes par les dates
Muffins aux xxx (une recette "paramétrée")
- Faire chauffer le four à 375f
- Mélanger l'oeuf avec la cassonade, l'huile, la mélasse et les xxx
- Ajouter le gruau, le son de blé, la farine, ...
- Ajouter le lait en dernier
- Bien mélanger et mettre dans les moules à muffin
- Cuire environ 25 min à 375f
Remarques
- le "code" de l'algorithme (de la recette) est presque le même
- La seule chose qui change est la valeur de xxx qui est le paramètre de l'algorithme
- nous pourrions faire varier d'autres ingrédients, la température du four, le
temps de cuisson, etc.
Définition des méthodes
un algorithme paramétré = une méthode (ou une fonction)
Structure d'une méthode
- nom : preparerMuffins
- paramètres : fruits, température du four, le
temps de cuisson
- séquence d'actions : faire chauffer le four, mélanger l'oeuf avec la cassonade, l'huile, ...
- valeur de retour : plusieurs muffins
Terminologie Java
- paramètre = entrée
- valeur de retour = sortie
- séquence d'actions = séquence d'instructions =
l'implémentation de l'algorithme
- le nom et les types de paramètres = la signature de la méthode
- la méthode/fonction est invoquée ou appelée
Syntaxe
<déclaration de méthode> ::= <en-tête de méthode> <corps de méthode>
<en-tête de méthode> ::=
[<modificateur d'accès>] [<type de retour>]
<nom de méthode> "(" <liste de paramètres formels> ")"
<liste de paramètres formels> ::= <paramètre formel> [, <paramètre formel>]*
<paramètre formel> ::= <type> <identificateur>
<corps de méthode> ::= <bloc d'instructions>
<bloc d'instructions> ::= { [<instruction>]* }
exemples :
static double somme(double p1, double p2){
return p1 + p2;
}
static void somme(double p1, double p2){
double s = p1 + p2;
System.out.println("Somme = " + s);
}
Pourquoi les méthodes ?
- au lieu d'écrire le code entier du programme, nous le divisons en morceaux réutilisables
- le code est plus facile à comprendre
- facile de corriger les erreurs et d'apporter des
modifications
- plus facile de faire abstraction de certains détails sans importance
pour la méthode
- plus facile de diviser le travail parmi les membres d'une équipe
Utilisation des méthodes
- les méthodes correspondent à des opérateurs sur les objets
- des centaines de méthodes prédéfinies :
Integer.parseInt (
valeur_de_type_String )
;
Math.sin (
valeur_de_type_double )
;
- objet_de_type_String
. replace (
valeur_de_type_String ,
valeur_de_type_String )
;
System.out . print (
valeur_de_type_String )
;
Syntaxe
<appel de méthode> ::=
[ ( <nom de classe> | <expression de type objet> ) . ]
<nom de méthode> "(" <liste de paramètres effectifs> ")" ;
Note : la notation nom_de_classe.nom_de_methode (liste_de_parametres_effectifs)
s'applique aux méthodes qui ne font pas d'opérations
sur un objet; elles sont appelées méthodes statiques
ou méthodes de classe
Exemples :
Remarques
- l'ordre des paramètres est important :
uneChaineDeCaracteres.replace("ab", "cd") est très différent de uneChaineDeCaracteres.replace("cd", "ab")
- paramètre effectif (actuel) = une expression dont le
type est convertible au type du paramètre formel
paramètre formel = une variable locale
initialisée avec la valeur du paramètre effectif lorsque la méthode est appelée
exemple :
static double somme(double p1, double p2){
return p1 + p2;
}
double x = somme(1, 2.9);
Remarque : la valeur 1 de type int
sera convertie en
une valeur 1.0 de type double
et cette dernière sera
utilisée pour initialiser p1
exemple :
static double somme(float p1, float p2){
return p1 + p2;
}
double x = somme(1, 2.9);
Remarque : le littéral 2.9 est par défaut de type double
;
il ne peut pas être converti en une valeur de type float
sans perte de précision
- le nombre et le type de paramètres dans la déclaration et dans l'appel doivent correspondre; sinon, une erreur de compilation sera détectée
- même si une méthode change ses paramètres formels,
les valeurs des paramètres effectifs ne seront pas changées
exemple :
public static void afficherSomme(int i, int j) {
i = i + j;
System.out.println(i);
}
public static void main(String[] args) {
int k = 1, m = 2;
afficherSomme(k, m);
System.out.println(k); // k == 1
}
Résultats :
3
1
- une méthode peut retourner une valeur
- si une méthode ne retourne pas de valeur, le type de retour
est
void
l'exécution de la méthode est terminée si la dernière instruction a été
exécutée ou l'instruction retour;
est exécutée
- si une méthode retourne une valeur, le type de retour doit être spécifié
la valeur retournée peut être utilisée comme une expression de
son type
exemple :
public int max(Vector v){
...
return v.elementAt(3);
}
Vector v = ...;
int i = max(V) + 5;
l'exécution de la méthode est terminée si l'instruction retour
une_expression;
est exécutée
- si une méthode est appelée dans la même classe, l'objet est connu; on peut donc utiliser une syntaxe plus simple :
nomDeMethode ( listeDesParamètresActuels );
Quiz
Identifiez les instructions valides pour chaque méthode définie ci-dessous :
void f(int i, int j){
return;
}
|
|
int f(int i, int j){
return i;
}
|
|
|
|
Conception des méthodes
Métodes accesseurs vs. métodes mutateurs
- métodes accesseurs : des méthodes
dont l'appel permet d'obtenir la valeur d'une propriété particulière de l'objet mais la valeur de l'objet ne sera pas modifiée;
le type de retour n'est pas void
exemple :
double getPerimetre(){
return 2*a + 2*b; // a et b représentent les deux côtés du rectangle
}
...
Rectangle r;
...
double perimetre = r.getPerimetre();
- métodes mutateurs : des méthodes dont
l'appel permet de définir la valeur d'une propriété particulière de l'objet;
en général, le type de retour est void
exemple :
void setCouleurFond(col){
couleur = col; // couleur représente la couleur de fond du rectangle
}
...
Rectangle r;
...
r.setCouleurFond("#FFAA80");
Il existe aussi des méthodes appelées constructeurs dont le but
est de créer des objets.
Comment construire une méthode ?
- identifiez des opérations dans l'algorithme de solution de notre problème
- des opérations qui sont utilisées plusieurs fois ou qui constituent des
unités naturelles de conception
- choisir un nom qui reflète la tâche effectuée par la méthode
- un verbe si on modifie un objet
- un nom ou un verbe si on accède à un attribut d'un objet
exemples : estEgal, setPerimetre, getPerimetre (perimetre), colorer, inscrire
- identifier les paramètres
- choisir les noms des paramètres
- identifier le type de retour
- écrire le pseudocode de l'algorithme
- traduire le pseudocode en Java
- tester le code
Exemple
Probleme : trouver les solutions d'une équation du second degré
Une équation du second degré se présente sous la forme suivante :
ax2 + bx + c
Les étapes :
- nom de la méthode : racine
- coefficients de l'équation (de type
double
)
- noms de paramètres : a, b, c
- pas de type de retour (la méthode affichera directement les solutions trouvées)
- pseudocode :
racine(a, b, c) {
delta = "discriminant" // b2 - 4ac
si discriminant == 0 alors
x1 = -b/2a
si discriminant > 0 alors
x1 = (-b - "racine carrée"(discriminant))/2a
x2 = (-b + "racine carrée"(discriminant))/2a
si discriminant < 0 alors
System.out.println("Il n'y a pas de solution");
si discriminant == 0 alors
System.out.println("Il y a une solution : x = " + x1);
si discriminant > 0 alors
System.out.println("Il y a deux solutions : x1 = " + x1 + ", x2 = " + x2);
}
- code :
static void racine (double a, double b, double c){
double x1 = 0;
double x2 = 0;
double delta = b * b - 4 * a * c;
if (delta == 0)
x1 = -b / 2.0 / a;
else if (delta > 0){
x1 = (-b - Math.sqrt(delta))/(2 * a);
x2 = (-b + Math.sqrt(delta))/(2 * a);
}
if (delta < 0)
System.out.println("Il n'y a pas de solution");
else if (delta == 0)
System.out.println("Il y a une solution : x = " + x1);
else
System.out.println("Il y a deux solutions : x1 = " + x1 + ", x2 = " + x2);
}
- tests :
racine(1, 0, 1);
racine(1, 2, 1);
racine(1, 0, -1);