Méthodes et surcharge des méthodes en Java
Une méthode est un module de programme contenant une série d'instructions permettant d'exécuter une tâche. Vous avez déjà vu des classes Java contenant une méthode main(), qui s'exécute automatiquement lorsque vous exécutez un programme.
La méthode main() d’un programme peut exécuter des méthodes supplémentaires, et ces méthodes peuvent en exécuter d’autres.
Toute classe peut contenir un nombre illimité de méthodes et chaque méthode peut être appelée un nombre illimité de fois.
Une méthode main() s'exécute automatiquement lorsque vous exécutez un programme, mais d'autres méthodes ne s'exécutent pas simplement parce que vous les placez dans une classe - elles doivent être appelées. Une classe peut contenir des méthodes qui ne sont jamais appelées à partir d'une application particulière, tout comme certains périphériques électroniques peuvent contenir des fonctionnalités que vous n'utilisez jamais. Par exemple, vous pouvez utiliser un enregistreur numérique pour lire des films mais jamais pour enregistrer des programmes télévisés.
Lorsque les programmeurs utilisent l'abstraction, ils utilisent un nom de méthode général dans un module plutôt que de répertorier toutes les activités détaillées qui seront exécutées par la méthode.
Création d'une méthode
Syntaxe :
modificateur returnType nomDeMethode(Liste des paramètres) { // en-tête de la méthode // corps ou contenu de la méthode }
Chaque méthode doit inclure les deux parties décrites dans la syntaxe
- En-tête - L’en-tête de la méthode fournit des informations sur la manière dont les autres méthodes peut interagir avec elle. Un en-tête de méthode est également appelé une déclaration.
- Un corps de la méthode entre deux accolades: le corps de la méthode contient les instructions permettant d'effectuer le travail de la méthode.
Un corps de la méthode est appelé sa mise en œuvre (implémentation). Techniquement, une méthode n'est pas obligée de contenir des instructions dans son corps, mais vous n'avez généralement aucune raison de créer une méthode vide dans une classe. (Parfois, lors du développement d'un programme, le programmeur crée une méthode vide en tant qu'espace réservé et complète l'implémentation ultérieurement. Une méthode vide s'appelle un stub.)
Exemple 1 :
public class Personne{ private Integer age; private String nom; // une méthode affiche() sans paramètres public void affiche(){ // corps } public String getNom(){ return this.nom; } public static void main(String args[]){ Personne p=new Personne(); p.affiche(); } }
L'en-tête de la méthode est la première ligne d'une méthode. Il contient les éléments suivants:
- Modificateurs d'accès optionnels
- Un type de retour
- Un identificateur
- Parenthèses
Modificateurs d'accès
Le modificateur d'accès pour une méthode Java peut être l'un des modificateurs suivants: public, private, protected ou, si non spécifié, package par défaut. Le plus souvent, les méthodes sont accessibles au public.
Une méthode doter d'un accès public signifie que toute autre classe peut l'utiliser, pas seulement la classe dans laquelle réside la méthode.
De plus, toute méthode pouvant être utilisée sans instancier un objet nécessite le modificateur de mot-clé static (Méthode de classe). La méthode main() dans une application doit utiliser le mot clé static, mais d'autres méthodes, telles que affiche(), peuvent également l'utiliser.
Type de retour
Un type de retour décrit le type de données que la méthode renvoie à sa méthode appelante. toutes les méthodes ne doivent pas nécessairement renvoyer une valeur à leurs méthodes d'appelantes; une méthode qui retourne aucune donnée a un type de retour void. La méthode main() dans une application doit avoir un type de retour void; Dans cet exemple, getNom() a String comme type de retour.
Un identificateur
Le nom d’une méthode peut être n’importe quel identifiant légal. Autrement dit, à l'instar des identifiants de classes et de variables, l'identifiant d'une méthode doit être un mot sans espaces, et ne peut pas être un mot-clé Java.
La méthode qui s'exécute en premier lorsque vous exécutez une application doit être nommée main(), mais vous avez beaucoup de choix pour nommer les autres méthodes que vous créez. Techniquement, vous pouvez même nommer une autre méthode main() à condition de ne pas inclure String [] dans les parenthèses, mais cela risquerait d'être source de confusion et n'est pas recommandé. Parce que les méthodes "font" quelque chose - c'est-à-dire effectuent une action - leurs noms contiennent souvent un verbe, tel que afficher ou calculer, etc.
Voir Identifiants et mots clés en java
Parenthèses
chaque en-tête de méthode contient un ensemble de parenthèses qui suivent l'identificateur. Les parenthèses peuvent contenir des données à envoyer à la méthode. Par exemple, lorsque vous écrivez une méthode main() dans une classe, les parenthèses dans son en-tête entourent String [] args. La méthode afficher() de la classe Personne ne nécessite aucune donnée extérieure; ses parenthèses sont donc vides.
Appeler une méthode
Les méthodes d'instance sont accessibles via des objets créés.
Vous pouvez accéder aux membres à l'aide de l'opérateur point ".".
Syntaxe:
// D'abord créer un objet ReferenceObjet = new Constructor() // appelez une méthode d'instance ReferenceObjet.nomMethode()
Exemple 2 :
class Lampe { // variable d'instance (attribut) private boolean isOn; // constructeur par défaut public Lampe(){ this.isOn=false; } // méthode d'instance public void allumer() { isOn = true; System.out.println("Allumer "); } // méthode de classe public static void ClassMethod() { System.out.println("je suis une méthode de classe "); } // méthode principale public static void main(String args[]){ Lampe l1= new Lampe(); l1.allumer(); Lampe.ClassMethod(); } }
je suis une méthode de classe
Passer des paramètres aux méthodes
Certaines méthodes exigent que des éléments de données leur soient envoyés lors de leur appelle. Les éléments de données que vous utilisez dans un appel à une méthode sont appelés des arguments. Lorsque la méthode reçoit les éléments de données, ils sont appelés paramètres. Les méthodes qui reçoivent des données sont flexibles car elles peuvent produire des résultats différents en fonction des données reçues.
les programmes orientés objet utilisent le masquage d'implémentation, qui décrit l'encapsulage des détails de la méthode. Cela signifie qu'un client n'a pas besoin de savoir comment une méthode fonctionne en interne, mais doit seulement connaître le nom de la méthode appelée et le type d'informations à envoyer. (En règle générale, vous souhaitez également connaître les données renvoyées par la méthode;) En d'autres termes, la méthode appelante doit uniquement comprendre l'interface avec la méthode appelée. L’interface est la seule partie d’une méthode que le client de la méthode voit ou avec laquelle il interagit.
Si une méthode peut recevoir un paramètre ou pas, sa déclaration contient les mêmes éléments que ceux qui n'acceptent pas de paramètre: modificateurs d'accès facultatifs, type de retour de la méthode, nom de la méthode et ensemble de parenthèses. Cependant, si une méthode reçoit un paramètre, deux éléments supplémentaires sont requis entre parenthèses:
- Le type de paramètre
- Un nom local pour le paramètre
Vous pouvez transmettre plusieurs arguments à une méthode en les répertoriant dans l'appel de la méthode et en les séparant par des virgules.
La signature d’une méthode est la combinaison du nom de la méthode et du nombre, des types et de l’ordre des arguments. Par conséquent, vous pouvez dire qu’un appel de méthode doit correspondre à la signature de la méthode appelée.
dans l'exemple ci-dessous, la variable "monnom" est un parmètre réel et "nom" dans la méthode afficher() est un paramètre formel
Exemple 3 :
public class Test{ public static void afficher(String nom){ System.out.println("Bonjour "+nom); } public static void main(String args[]){ String monnom="ESSADDOUKI"; afficher(monnom); } }
En Java, tous les primitifs tels que int, char, etc. sont passés par valeur, mais tous les non-primitifs (ou objets de toute classe) sont toujours des références. Cela devient donc délicat lorsque nous passons des références d'objet à des méthodes. Java crée une copie des références et la transmet à la méthode, mais celles-ci pointent toujours sur la même référence mémoire. Ainsi, l'objet de la méthode appelante ainsi que sa référence resteront inchangés.
Les modifications ne sont pas reflétées si nous modifions l'objet lui-même pour désigner un autre emplacement ou un autre objet.
Exemple 4 :
class Personne { private int age; private String nom; public Personne(int age, String nom) { this.age = age; this.nom = nom; } public void setNom(String nom) { this.nom = nom; } public String getNom() { return nom; } } // classe de teste public class Test { public static void main(String args[]) { Personne p = new Personne(32, "ESSADDOUKI"); changerNom(p, "Kayouh"); System.out.println("le nom de p est " + p.getNom()); changerNom2(p, "Moutawakil"); System.out.println("le nom de p est " + p.getNom()); } // passage par référence public static void changerNom(Personne p, String name) { p.setNom(name); } public static void changerNom2(Personne p, String name) { // Nous avons changé la référence pour faire référence à un autre emplacement. // Toutes les modifications apportées à la référence ne // sont pas reflétées dans main () p = new Personne(42, name); } }
le nom de p est Kayouh
Différence entre un argument et un paramètre
Argument | Paramètre |
Lorsqu'une méthode est appelée, les valeurs transmises lors de l'appel sont appelées arguments. | Les valeurs qui sont écrites lors de la définition de la méthode sont appelées paramètres. |
Ceux-ci sont utilisés dans l'instruction d'appel de méthode pour envoyer une valeur de la méthode appelante à la méthode appelée. | Ceux-ci sont utilisés dans l'en-tête de la méthode appelée pour recevoir la valeur des arguments. |
Pendant l'appel, chaque argument est toujours attribué au paramètre dans la définition de la méthode. | Les paramètres sont des variables locales auxquelles sont attribués les arguments lorsque la méthode est appelée. |
Ils sont aussi appelés paramètres réels | Ils sont aussi appelés paramètres formels |
Arguments variables (Varargs)
Dans JDK 5, Java a inclus une fonctionnalité qui simplifie la création de méthodes devant prendre un nombre variable d’arguments. Cette fonctionnalité s'appelle varargs et est une forme abrégée pour les arguments de longueur variable. Une méthode qui prend un nombre variable d'arguments est une méthode varargs.
Avant JDK 5, les arguments de longueur variable pouvaient être traités de deux manières. Une méthode surchargée (une pour chaque) et une autre placent les arguments dans un tableau, puis transmettent ce tableau à la méthode. Les deux sont potentiellement sujets aux erreurs et nécessitent plus de code. La fonction varargs offre une option plus simple et meilleure.
Syntaxe :
Un argument de longueur variable est spécifié par trois points (...). Par exemple :
public void afficher(String ... noms){ // corps de la méthode }
Cette syntaxe indique au compilateur que afficher() peut être appelée avec zéro argument ou plus. En conséquence, ici, noms est implicitement déclaré comme un tableau de type String[]. Vous trouverez ci-dessous un extrait de code illustrant le concept ci-dessus:
Exemple 5 :
public class Test{ public static void afficher(String ... noms){ for (String nom : noms) { System.out.println(nom); } } public static void main(String args[]){ afficher("Mostafa", "Ismail", "Dounia", "Omar", "Sara"); } }
Ismail
Dounia
Omar
Sara
- La syntaxe ... indique au compilateur que varargs a été utilisé et que ces arguments doivent être stockés dans le tableau désigné par noms.
- La variable "noms" est exploitée comme un tableau. Dans ce cas, nous avons défini le type de données de "noms" comme String. Donc, cela ne peut prendre que des valeurs de String. Le nombre d'arguments peut être trouvé en utilisant noms.length, la façon dont nous trouvons la longueur d'un tableau en Java.
int nums(int a, float b, double … c)
Dans ce cas, les deux premiers arguments sont mis en correspondance avec les deux premiers paramètres et les arguments restants appartiennent à c.
Exemple 6 :
public class Test { public static void afficher(int annee, String ecole, String... noms) { System.out.println("Annee : " + annee); System.out.println("Ecole : " + ecole); for (String nom : noms) { System.out.println(nom); } } public static void main(String args[]) { afficher(2019, "ESTM", "Mostafa", "Ismail", "Dounia", "Omar", "Sara"); } }
Ecole : ESTM
Mostafa
Ismail
Dounia
Omar
Sara
Surcharge des méthodes
La surcharge permet à différentes méthodes d’avoir le même nom, mais des signatures différentes où la signature peut différer en fonction du nombre de paramètres d’entrée, du type de paramètres d’entrée ou des deux.
Exemple 7 :
public class Test { // Cette méthode prend deux paramètres int public int somme(int x, int y) { return (x + y); } // Cette méthode prend trois paramètres int public int somme(int x, int y, int z) { return (x + y + z); } // Cette méthode prend deux paramètres double public double somme(double x, double y) { return (x + y); } public static void main(String args[]) { Test t = new Test(); System.out.println(t.somme(10, 20)); System.out.println(t.somme(10, 20, 30)); System.out.println(t.somme(10.5, 20.5)); } }
60
31.0
Et si le prototype exact ne correspond pas aux arguments.
En termes de priorité, le compilateur prend les mesures suivantes:
- Conversion de type mais vers un type plus élevé (en termes de plage) dans la même catégorie.
- Conversion de type dans la catégorie immédiatement supérieure (supposez qu'il n'y ait pas de type de données long disponible pour un type de données int, alors il recherchera le type de données float).
Exemple 8 :
public class Test { public void afficher(String s) { System.out.println("je suis un String : " + s); } public void afficher(int a) { System.out.println("je suis un int : " + a); } public static void main(String args[]) { Test t = new Test(); // String t.afficher("Mostafa"); // Puisque char n'est pas disponible, le type de données // supérieur à char en termes de plage est int. t.afficher('A'); // int t.afficher(435); // comme le type de données float n'est pas disponible et même un // type de données plus élevé, il y aura donc une erreur à cette étape. t.afficher(4.5); } }
Quel est l'avantage?
Nous n’avons pas besoin de créer et de mémoriser des noms différents pour des méthodes faisant la même chose. Par exemple, dans notre code, si la surcharge n'était pas prise en charge par Java, il faudrait créer des noms de méthodes tels que somme1, somme2,… ou somme2Int, ... etc.
Peut-on surcharger les méthodes sur le type de retour?
Nous ne pouvons pas surcharger par type de retour.
Exemple 9 :
public class Test { public int getValue(){ // corps } // erreur du compilateur: getValue() est déjà définie public String getValue(){ // corps } }
Peut-on surcharger les méthodes statiques?
La réponse est oui. Nous pouvons avoir deux méthodes statiques ou plus portant le même nom, mais avec des différences dans les paramètres d'entrée.
Peut-on surcharger main()
Comme d'autres méthodes statiques, nous pouvons surcharger main() en Java.
Java prend-il en charge la surcharge des opérateurs?
Contrairement à C ++, Java n'autorise pas les opérateurs surchargés définis par l'utilisateur.