W3docs

Les méthodes de classe en Java

Ajoutez des méthodes d'instance à une classe Java pour donner un comportement aux objets et opérer sur leurs champs.

Les méthodes d'une classe sont ce qui donne un comportement à ses objets. Les champs définissent ce qu'un objet est ; les méthodes décrivent ce qu'il peut faire. Jusqu'à présent, les méthodes que vous avez écrites étaient static — des utilitaires appartenant à la classe elle-même. Ce chapitre traite des méthodes d'instance, qui appartiennent à chaque objet et opèrent sur ses champs.

Le terme « méthodes de classe » en Java est un peu ambigu. La plupart des auteurs l'utilisent pour désigner les méthodes définies à l'intérieur d'une classe — ce qui inclut les deux types. Certains l'emploient strictement pour désigner les méthodes static (car celles-ci appartiennent littéralement à la classe). Nous couvrirons ici les méthodes d'instance, et les méthodes static font l'objet de leur propre chapitre sur Java static.

Une méthode d'instance

Ajoutez une méthode dans le corps de la classe, sans static, et elle devient une partie de chaque instance :

public class Circle {
  double radius;

  double area() {
    return Math.PI * radius * radius;
  }
}

Maintenant, chaque Circle que vous créez peut répondre à area() :

Circle c = new Circle();
c.radius = 5;
System.out.println(c.area());   // 78.539...

Le corps utilise radius sans le qualifier — Java résout le nom nu comme this.radius, le champ de l'objet sur lequel la méthode a été appelée.

this — le récepteur

Chaque méthode d'instance possède un paramètre invisible appelé this, qui fait référence à l'objet sur lequel la méthode a été appelée :

Circle a = new Circle();   a.radius = 2;
Circle b = new Circle();   b.radius = 5;

a.area();    // inside area(), this == a, so this.radius == 2
b.area();    // inside area(), this == b, so this.radius == 5

La même méthode compilée s'exécute dans les deux cas ; ce qui change, c'est l'objet auquel this fait référence. Le chapitre sur le mot-clé this explique quand vous devez écrire this. explicitement et quand vous pouvez l'omettre.

Méthodes qui modifient l'état

Une méthode peut également écrire dans des champs. De telles méthodes sont souvent appelées mutateurs :

public class Counter {
  int count;

  void increment() {
    count++;            // mutates this.count
  }
  void reset() {
    count = 0;
  }
  int get() {
    return count;
  }
}

Counter c = new Counter();
c.increment(); c.increment(); c.increment();
System.out.println(c.get());   // 3

La mutation via des méthodes est la façon dont les objets évoluent dans le temps sans que le code extérieur ne touche directement à leurs champs. Les méthodes qui se contentent de lire un champ et de le renvoyer en sont l'image miroir — on les appelle généralement accesseurs ou getters (int get() ci-dessus en est un exemple). Faire passer les lectures et les écritures par des méthodes, plutôt que d'exposer les champs, est l'idée centrale derrière l'encapsulation : l'objet reste maître de ses propres données.

Appeler d'autres méthodes depuis l'intérieur

Les méthodes d'instance peuvent appeler d'autres méthodes sur le même objet, simplement par leur nom :

public class Rectangle {
  double width, height;

  double area()      { return width * height; }
  double perimeter() { return 2 * (width + height); }

  String describe() {
    return "area=" + area() + ", perimeter=" + perimeter();
  }
}

Le compilateur transforme area() et perimeter() à l'intérieur de describe en this.area() et this.perimeter(). Ils appellent les méthodes sur le rectangle sur lequel describe a été invoquée.

Méthodes statiques vs méthodes d'instance — laquelle choisir

La règle générale : la méthode dépend-elle de l'état propre à l'objet ?

  • Si oui, c'est une méthode d'instance (sans static).
  • Si non, c'est une méthode static.
public class Math2 {
  public static int squared(int n) {       // pure calculation — static
    return n * n;
  }
}

public class Counter {
  int count;
  public void increment() {                // reads/writes this.count — instance
    count++;
  }
}

Un signe révélateur fréquent est une méthode d'instance qui ignore complètement this — c'est une méthode static déguisée. Le chapitre sur Java static passe en revue les compromis à considérer.

Appeler une méthode d'instance nécessite une instance

Puisque les méthodes d'instance lisent this, vous ne pouvez pas en appeler une sans objet :

Counter.increment();      // ERROR — increment is not static
new Counter().increment(); // fine — increment is called on a fresh Counter (which is then thrown away)

Counter c = new Counter();
c.increment();             // fine — increment is called on c

C'est l'erreur de compilation la plus fréquente chez les débutants : une méthode non statique référencée depuis un contexte statique (typiquement depuis main, qui est lui-même statique).

Avertissement

Si le compilateur affiche non-static method increment() cannot be referenced from a static context, vous avez presque certainement appelé une méthode d'instance sans objet — par exemple Counter.increment() au lieu de c.increment(). Créez d'abord une instance, puis appelez la méthode sur elle.

Surcharge et redéfinition

Les méthodes d'instance prennent en charge les deux :

  • Surcharge (overloading) : plusieurs méthodes portant le même nom mais avec des listes de paramètres différentes dans la même classe (traitée dans la surcharge de méthodes).
  • Redéfinition (overriding) : une sous-classe remplace la version héritée d'une méthode (traitée dans la redéfinition de méthodes).

Vous avez déjà vu la surcharge dans la Partie 5. La redéfinition est l'un des grands avantages de l'héritage et sera abordée prochainement.

Le corps d'une méthode est un bloc

Le corps d'une méthode est simplement un bloc de code ordinaire — les variables que vous y déclarez sont locales à l'appel, le flux de contrôle fonctionne de la même manière qu'ailleurs, et vous pouvez retourner prématurément. Rien dans le fait que « c'est dans une classe » ne change la façon dont le corps lui-même se lit. La seule capacité supplémentaire est que les identifiants nus peuvent désormais faire référence aux champs de l'objet et à ses autres méthodes.

Un exemple complet

Cet exemple regroupe des accesseurs (area, perimeter), un mutateur (scale) et une méthode qui appelle d'autres méthodes (describe) dans une seule classe. Rectangle est déclarée static class uniquement pour que toute la démonstration tienne dans un seul fichier — ce mot-clé s'applique à la classe imbriquée, et non à ses méthodes d'instance, qui s'exécutent toujours sur un rectangle spécifique. Notez que mettre r à l'échelle ne modifie pas s : chaque objet porte son propre état.

java— editable, runs on the server

La suite

Jusqu'à présent, vous avez créé des objets en écrivant new Dog(), puis en renseignant les champs ligne par ligne. C'est verbeux et sujet aux erreurs — et facile à oublier. La solution est un constructeur, une méthode spéciale qui s'exécute lors de la création de l'objet. Continuez vers le chapitre sur les constructeurs.

Pratique

Pratique
Quelle est la différence entre une méthode statique et une méthode d'instance ?
Quelle est la différence entre une méthode statique et une méthode d'instance ?
Was this page helpful?