IFT 1179 : Programmation en C#
A) Redéfinition de méthode :
On a déjà vu la surcharge des méthodes :des méthodes différentes qui portement le même nom.
En C#, object est la classe parente au sommet de
l’hiérarchie des classes prédéfinies en C# ou inventées par l’usager. Dans object, parmi d’autres méthodes, on y
trouve :
1. public string ToString()
la présentation d’un objet en chaîne de caractères qu’on utilise dans l’affichage, dans la
concaténation.
2. public bool Equals(object autre)
retourne vrai ou faux selon ce que l’objet courant dispose du même contenu qu’un autre objet
La notion de redéfinition d’une méthode implique qu’on
écrit une méthode dans une classe qui respecte la syntaxe
d’une méthode existence dans une classe parente.
1) Redéfinition de ToString() :
a) Cas 1 : la classe ne dispose pas de ToString()
C# remonte dans l’hiérarchie et applique la méthode ToString() d’une classe parente. Si C# applique cette méthode de object, il retourne le nom de la classe.
Soient deux personnes construites d’une classe nommée Personne qui ne dispose pas de redéfinition de ToString :
Personne pers1 = new Personne("Tremblay Pierre", 1.78, 65.8);
Console.WriteLine("Informations de la premiere personne : " + pers1.ToString());
Personne pers2 = new Personne("Charbonneau Lise", 1.62, 58.9);
Console.WriteLine("Informations de la deuxieme personne : " + pers2);
On obtient l’exécution suivante :
Informations de la premiere personne : Personne Informations de la deuxieme personne : Personne Press any key to continue
b) Cas 2 : la classe redéfinit la méthode ToString() 1. style classique dans les langages de la POO :
public override string ToString()
{ return 1 chaîne de caractères représentant l’objet }
Exemple : on redéfinit ToString() dans la classe Personne comme la suivante :
public override string ToString() {
return nomPre + " " + taille + " metre, " + poids + " kg";
}
On obtient alors :
Informations de la premiere personne : Tremblay Pierre 1,78 metre, 65,8 kg
Informations de la deuxieme personne : Charbonneau Lise 1,62 metre, 58,9 kg
Press any key to continue
2. nouveau style de C# (et de version 1.5 de Java) :
On utilise la méthode string.Format pour retourner une chaîne formatée. Exemple
public override string ToString() {
return string.Format("{0, 15} {1, 6:F2} metre {2, 5:F1} kg", nomPre, taille, poids);
}
Lors de l’exécution, on obtient :
Informations de la premiere personne : Tremblay Pierre 1,78 metre 65,8 kg
Informations de la deuxieme personne : Charbonneau Lise 1,62 metre 58,9 kg
Press any key to continue
2) Redéfinition de Equals (object obj):
Entre deux objets :
obj1 = obj2 ; l’objet 1 réfère vers la m^me zone de mémoire que l’objet 2
obj1 == obj2 ces deux objets réfèrent-ils vers la même zone de mémoire ?
Avec pers1 et pers2 construits précédemment, l’instruction Console.WriteLine("pers1 == pers2 vaut " +
(pers1 == pers2));
affiche false
Par contre, les deux instructions :
pers1 = pers2;
Console.WriteLine("pers1 == pers2 vaut " + (pers1 == pers2));
font afficher : true
Pour comparer le contenu de 2 objets, on utilise plutôt la méthode Equals :
Dans object, cette méthode compare selon la référence car les auteurs de cette méthode ne savent rien sur les classes créées plus tard pour comparter le contenu de deux objets.
public bool Equals(object autre)
a) Cas 1 : la classe ne dispose pas de Equals(...) C# remonte dans l’hiérarchie et applique la méthode
Equals(. . .) d’une classe parente. Si C# applique cette méthode de object, il retourne la comparaison entre deux références (au lieu de leurs contenus).
On ajoute la troisième personne qui a le même contenu de la première personne :
Console.WriteLine("pers1.Equals(pers2) vaut " + pers1.Equals(pers2));
Personne pers3 = new Personne("Tremblay Pierre", 1.78, 65.8);
Console.WriteLine("pers1.Equals(pers3) vaut " + pers1.Equals(pers3));
L’exécution donne :
pers1.Equals(pers2) vaut False pers1.Equals(pers3) vaut False Press any key to continue
Cas 2 : redéfinition de Equals(...)
a) version plus simple (cas de la classe Personne)
public override bool Equals(object obj) {
Personne autre = (Personne) obj;
return nomPre.ToUpper().Equals(autre.nomPre.ToUpper());
}
L’exécution du codage précédent nous donne :
pers1.Equals(pers2) vaut False pers1.Equals(pers3) vaut True Press any key to continue b) version plus détaillée :
Les experts en POO suggèrent toujours de respecter : 1. obj.Equals(obj) retourne toujours True;
2. obj1.Equals(obj2) et obj2.Equals(obj1) disposent toujours du même résultat
3. Si obj1.Equals(obj2) vaut True et obj2.Equals(obj3) vaut True alors obj1.Equals(obj3) vaut aussi True
De plus, une comparaison du genre pers.Equals(unCercle) devrait retourner toujours False (objets incompatibles).
Voici l’exemple de redéfinition de Equals dans la classe Station (des métros) :
public override bool Equals (object obj) {
if (this == obj)
return true; // comparer à lui-même else
if (obj.GetType() != this.GetType()) // incomparable!
return false;
else {
Station autre = (Station) obj;
return nom.ToUpper().Equals(autre.nom.ToUpper());
} }
Les méthodes de recherche séquentielle dans les
collections (exemple Array) sont basées sur la
redéfinition de Equals.
Fichier : Redefinition0.cs (aucune redéfinition) :
/* Redefinition0.cs
* Pas de redénition de ToString ni de Equals *
*/
using System;
using System.IO;
class Personne {
// champs (field) d'informations private string nomPre;
private double taille;
private double poids;
// un constructeur
public Personne(string nomPre, double taille, double poids) {
this.nomPre = nomPre;
this.taille = taille;
this.poids = poids;
}
// AUCUNE redéfinition }
class Redefinition0 {
static void Main(string[] args) {
Personne pers1 = new Personne("Arcand Pierre",1.75, 65.4), pers2 = new Personne("Charbonneau Luc",1.89, 76.2), pers3 = new Personne("Arcand Pierre",1.75, 65.4);
Console.WriteLine("Infos de pers1 : " + pers1.ToString());
Console.WriteLine("pers1 = pers3 vaut : " + (pers1 == pers3));
Console.WriteLine("pers1.Equals(pers3) vaut : " + pers1.Equals(pers3));
} }
/* Exécution:
Infos de pers1 : Personne pers1 = pers3 vaut : False
pers1.Equals(pers3) vaut : False Press any key to continue
*/
Fichier : Redefinition1.cs (redéfinition, style simple)
/* Redefinition1.cs
* On redéfinit de ToString et de Equals * Style simple
*/
using System;
using System.IO;
class Personne {
// champs (field) d'informations private string nomPre;
private double taille;
private double poids;
// un constructeur
public Personne(string nomPre, double taille, double poids) {
this.nomPre = nomPre;
this.taille = taille;
this.poids = poids;
}
public override string ToString() {
return nomPre + " " + taille + " metre, "
+ poids + " kg";
}
public override bool Equals(object obj) {
// version SIMPLE
return nomPre.ToUpper().Equals ( ((Personne) obj).nomPre.ToUpper());
} }
class Redefinition0 {
static void Main(string[] args) {
Personne pers1 = new Personne("Arcand Pierre",1.75, 65.4), pers2 = new Personne("Charbonneau Luc",1.89, 76.2), pers3 = new Personne("Arcand Pierre",1.75, 65.4);
Console.WriteLine("Infos de pers1 : " + pers1.ToString());
Console.WriteLine("pers1 = pers3 vaut : " +
(pers1 == pers3));
Console.WriteLine("pers1.Equals(pers3) vaut : " + pers1.Equals(pers3));
} }
/* Exécution:
Infos de pers1 : Arcand Pierre 1,75 metre, 65,4 kg pers1 = pers3 vaut : False
pers1.Equals(pers3) vaut : True Press any key to continue
*/
Fichier:Redefinition2.cs (redéfinition, style plus complet)
/* Redefinition2.cs
* On redéfinit de ToString et de Equals * Style plus complet
*/
using System;
using System.IO;
class Personne {
// champs (field) d'informations private string nomPre;
private double taille;
private double poids;
// un constructeur
public Personne(string nomPre, double taille, double poids) {
this.nomPre = nomPre;
this.taille = taille;
this.poids = poids;
}
public override string ToString() {
return string.Format("{0, 15} {1, 6:F2} metre {2, 7:F1} kg", nomPre, taille, poids);
}
public override bool Equals(object obj) {
if (this == obj) // comparer à lui-même return true;
else
if ( this.GetType() != obj.GetType() ) return false;
else
return nomPre.ToUpper().Equals ( ((Personne) obj).nomPre.ToUpper());
}
}
class Redefinition0 {
static void Main(string[] args) {
Personne pers1 = new Personne("Arcand Pierre",1.75, 65.4), pers2 = new Personne("Charbonneau Luc",1.89, 76.2), pers3 = new Personne("Arcand Pierre",1.75, 65.4);
Console.WriteLine("Infos de pers1 : " + pers1.ToString());
Console.WriteLine("pers1 = pers3 vaut : " +
(pers1 == pers3));
Console.WriteLine("pers1.Equals(pers3) vaut : " + pers1.Equals(pers3));
} }
/* Exécution:
Infos de pers1 : Arcand Pierre 1,75 metre 65,4 kg pers1 = pers3 vaut : False
pers1.Equals(pers3) vaut : True Press any key to continue
*/