Depuis le Chapitre 1, on écrit des méthodes — Demarrer(), AfficherInfos(), RecevoirDegats(), Ajouter()… — sans jamais en avoir posé le vocabulaire. Ce chapitre formalise tout ça : anatomie d'une méthode, type de retour, paramètres, le mot-clé this, la méthode magique ToString(). À la fin, tu sais lire et écrire n'importe quelle méthode d'une classe C# avec assurance.
Une classe, c'est des données (attributs, propriétés) et des actions (méthodes). Les chapitres précédents ont creusé les données. On s'attaque maintenant à l'autre moitié.
À la fin de ce chapitre, tu seras capable de :
void d'une méthode qui renvoie une valeur.this pour désigner l'objet courant.ToString() pour qu'un objet sache s'afficher tout seul.static).Voici une méthode typique :
public int Soigner(int montant)
{
int avant = pv;
Pv += montant;
int reellement = Pv - avant;
return reellement;
}
Elle se découpe en cinq parties :
public int Soigner (int montant) { ... }
│ │ │ │ │
│ │ │ │ └─ Corps
│ │ │ └─ Paramètres (entrées)
│ │ └─ Nom (PascalCase, action)
│ └─ Type de retour
└─ Visibilité (public / private)
| Élément | Rôle |
|---|---|
| Visibilité | Qui peut l'appeler ? public depuis n'importe où, private depuis la classe |
| Type de retour | Ce que la méthode renvoie (int, string, bool, void si rien…) |
| Nom | Verbe à l'impératif, en PascalCase : Demarrer, Soigner, Afficher |
| Paramètres | Les valeurs d'entrée. Zéro, un, ou plusieurs. Chacun avec son type |
| Corps | Le bloc { ... } qui exécute le travail |
void vs méthode qui renvoieDeux grandes familles de méthodes :
void — je fais quelque choseUne méthode void exécute une action et ne renvoie rien. On l'utilise pour ses effets : afficher, modifier l'état de l'objet, écrire dans un fichier…
public void Afficher()
{
Console.WriteLine($"{Nom} - {Pv}/{PvMax} PV");
}
Appel :
hero.Afficher(); // OK
int x = hero.Afficher(); // ❌ erreur : Afficher ne renvoie rien
Une méthode avec un type de retour doit obligatoirement contenir une instruction return qui renvoie une valeur de ce type.
public int Soigner(int montant)
{
int avant = pv;
Pv += montant;
return Pv - avant; // nombre réel de PV récupérés
}
Appel :
int soin = hero.Soigner(30);
Console.WriteLine($"Tu as récupéré {soin} PV.");
💡 Comment choisir ? Si ta méthode produit une information que l'appelant va utiliser ensuite, elle doit la renvoyer. Si elle ne fait qu'agir, elle est
void. Quand tu hésites, demande-toi : est-ce que celui qui appelle cette méthode a besoin d'une réponse ?
Une méthode peut prendre zéro, un ou plusieurs paramètres, chacun avec son type. Ils s'écrivent en camelCase.
public void Deplacer(int x, int y)
{
positionX = x;
positionY = y;
}
Le type d'un paramètre peut être une classe :
public void Attaquer(Personnage cible)
{
int degats = Attaque - cible.Defense;
if (degats < 0) degats = 0;
cible.Pv -= degats;
Console.WriteLine($"{Nom} attaque {cible.Nom} et inflige {degats} dégâts.");
}
Appel :
aragorn.Attaquer(legolas);
Du point de vue d'aragorn, legolas est passé sous le nom cible. Modifier cible.Pv modifie bien les PV de legolas — les objets sont passés par référence : on travaille sur l'original, pas sur une copie.
⚠️ Conséquence importante : les méthodes qui prennent un objet en paramètre peuvent modifier cet objet. Sois conscient de ce que tu fais. Si tu ne veux pas qu'une méthode modifie son paramètre, ne le modifie pas dans le corps.
thisthis désigne l'objet courant — l'instance sur laquelle la méthode est appelée.
Quand tu écris aragorn.Attaquer(legolas), à l'intérieur de la méthode Attaquer :
this désigne aragorn (l'objet sur lequel on appelle la méthode).cible désigne legolas (le paramètre).public void Attaquer(Personnage cible)
{
Console.WriteLine($"{this.Nom} attaque {cible.Nom}.");
// Strictement équivalent à : $"{Nom} attaque {cible.Nom}."
}
this.Nom et Nom font la même chose. Dans la plupart des cas, on omet this — il est implicite.
this devient indispensableSi un paramètre porte le même nom qu'un attribut, le compilateur prend le paramètre par défaut. this permet de désigner explicitement l'attribut :
public void Renommer(string nom)
{
this.nom = nom;
// ^---- ^----
// attribut paramètre
}
Sans this., la ligne nom = nom; ne ferait que se réaffecter le paramètre à lui-même — l'attribut ne changerait pas.
Parfois, un objet doit se passer en argument à une méthode d'un autre objet :
public void RejoindreEquipe(Equipe equipe)
{
equipe.Ajouter(this); // « ajoute MOI à l'équipe »
}
Ici this représente le personnage courant. Sans this, on ne saurait pas comment se référer à lui-même.
ToString() : la méthode universelleToutes les classes C# possèdent une méthode ToString() cachée qui renvoie une représentation textuelle de l'objet. Par défaut, elle renvoie le nom complet de la classe — pas très utile :
Personnage hero = new Personnage();
hero.Nom = "Aragorn";
Console.WriteLine(hero); // → "Personnage" (par défaut, pas génial)
Mais on peut la redéfinir dans notre classe pour fournir un affichage personnalisé :
public override string ToString()
{
return $"{Nom} ({Classe}) - Niv.{Niveau} - {Pv}/{PvMax} PV";
}
Maintenant :
Console.WriteLine(hero);
// Aragorn (Guerrier) - Niv.5 - 100/100 PV
Console.WriteLine appelle automatiquement ToString() sur l'objet — donc plus besoin de méthode Afficher() à part. L'interpolation $"{hero}" le fait aussi.
🧠 Le mot-clé
overridesignifie « je redéfinis une méthode qui existait déjà ». On verra exactement de qui elle vient quand on étudiera l'héritage. Pour l'instant, retiens juste qu'il est obligatoire pour redéfinirToString().
ToString()\n), pas d'effet de bord (pas d'écriture console à l'intérieur de ToString !).Toutes les méthodes vues jusqu'ici sont des méthodes d'instance : on a besoin d'un objet pour les appeler.
Personnage hero = new Personnage();
hero.Afficher(); // on appelle Afficher SUR un objet
Il existe une autre catégorie : les méthodes statiques, déclarées avec le mot-clé static. Elles n'appartiennent pas à un objet — elles appartiennent à la classe elle-même.
class Outils
{
public static int Maximum(int a, int b)
{
return a > b ? a : b;
}
}
// Appel : pas de "new", on appelle DIRECTEMENT sur la classe
int gros = Outils.Maximum(5, 12);
Tu en as déjà rencontré sans le savoir :
Console.WriteLine("..."); // WriteLine est static
Math.Sqrt(16); // Sqrt est static
int.Parse("42"); // Parse est static
C'est pour ça qu'on n'a jamais écrit Console maConsole = new Console();.
💡 Quand utiliser
static? Quand la méthode n'a pas besoin de l'état d'un objet particulier — typiquement des fonctions utilitaires (calculs, conversions, validation…). Si la méthode doit accéder à un attribut, elle ne peut pas être statique : il faut un objet.
Personnage enrichieVoici la classe avec son lot complet de méthodes :
class Personnage
{
// --- Attributs et propriétés (rappel Chap. 4) ---
private int pv;
public string Nom { get; set; }
public string Classe { get; set; }
public int PvMax { get; set; }
public int Niveau { get; set; }
public int Attaque { get; set; }
public int Defense { get; set; }
public int Pv
{
get { return pv; }
set
{
if (value < 0) value = 0;
if (value > PvMax) value = PvMax;
pv = value;
}
}
public bool EstVivant => pv > 0;
// --- Méthode void : action sans retour ---
public void Attaquer(Personnage cible)
{
int degats = Attaque - cible.Defense;
if (degats < 0) degats = 0;
cible.Pv -= degats;
Console.WriteLine($"{Nom} attaque {cible.Nom} et inflige {degats} dégâts.");
}
// --- Méthode typée : renvoie le soin réel ---
public int Soigner(int montant)
{
int avant = pv;
Pv += montant;
return pv - avant;
}
// --- Redéfinition de ToString ---
public override string ToString()
{
string etat = EstVivant ? "vivant" : "mort";
return $"{Nom} ({Classe}) - Niv.{Niveau} - {Pv}/{PvMax} PV - {etat}";
}
}
Program.csPersonnage aragorn = new Personnage();
aragorn.Nom = "Aragorn"; aragorn.Classe = "Guerrier";
aragorn.PvMax = 100; aragorn.Pv = 100;
aragorn.Attaque = 15; aragorn.Defense = 10; aragorn.Niveau = 5;
Personnage legolas = new Personnage();
legolas.Nom = "Legolas"; legolas.Classe = "Archer";
legolas.PvMax = 80; legolas.Pv = 80;
legolas.Attaque = 18; legolas.Defense = 7; legolas.Niveau = 5;
Console.WriteLine(aragorn);
Console.WriteLine(legolas);
aragorn.Attaquer(legolas);
legolas.Attaquer(aragorn);
int soin = aragorn.Soigner(15);
Console.WriteLine($"{aragorn.Nom} récupère {soin} PV.");
Console.WriteLine(aragorn);
Console.WriteLine(legolas);
⚠️ Tu remarques combien de lignes il faut pour initialiser
aragornetlegolas? Sept lignes par personnage, et on peut oublier d'en mettre une, ce qui crée un objet à moitié initialisé. C'est le problème que va résoudre le constructeur, au chapitre suivant.
Pour chacune des signatures suivantes, dis ce qu'elle renvoie et ce qu'elle prend en entrée :
| Signature | Renvoie | Prend |
|---|---|---|
public void Allumer() |
… | … |
public bool EstAllume() |
… | … |
public int Compter(string mot, char lettre) |
… | … |
public string Resumer() |
… | … |
public void Combiner(Inventaire autre) |
… | … |
Reprends ta classe CompteBancaire du Chapitre 4 et ajoute :
Transferer(double montant, CompteBancaire destinataire) : retire du compte courant et dépose sur le destinataire — si le solde est suffisant.EstRiche() : méthode qui renvoie true si le solde dépasse 10 000 €.ToString() : retourne une chaîne du type "Compte de Marie Dupont — solde : 1 245,00 €".Pour chacune des méthodes ci-dessous, indique si elle devrait être static ou méthode d'instance, et pourquoi :
| Méthode possible | static / instance ? |
|---|---|
Personnage.GenererPnj() qui crée un personnage aléatoire |
… |
aragorn.Soigner(20) |
… |
Math.Aleatoire(1, 100) |
… |
inventaire.Taille |
… |
Console.WriteLine(...) |
… |
Crée trois personnages (Aragorn, Legolas, Gimli) et fais-les se battre chacun leur tour :
Console.WriteLine(personnage).void = la méthode ne renvoie rien. Sinon, le corps doit contenir un return du bon type.int, string…) ou des objets (passés par référence).this désigne l'objet courant. Utile pour lever une ambiguïté ou se passer soi-même à une méthode d'un autre objet.ToString() se redéfinit avec override ; Console.WriteLine(obj) l'appelle automatiquement.aragorn.Attaquer(...)). Méthode static : appartient à la classe, pas d'objet nécessaire (Math.Sqrt(...)).On sait maintenant écrire et lire à peu près n'importe quelle méthode. Reste un problème qu'on a pointé du doigt plusieurs fois : créer un personnage prend 7 lignes, et on peut en oublier une. Au chapitre suivant, le constructeur va régler ça en garantissant qu'un objet naît directement dans un état valide, en une seule ligne d'instanciation.