L'auto-référencement
La surcharge des fonctions et
procédures
1.
L'AUTO-REFERENCEMENT
1.1.
Principe
Chaque méthode peut travailler sur les
données de l'objet ayant servi à son appel en indiquant uniquement
le nom des données.
Elle peut également appliquer une méthode
de la classe à l'objet ayant servi à son appel, en indiquent
uniquement le nom de la méthode.
La méthode peut retourner l'une des
données.
Mais il est possible que la méthode ait
besoin de retourner l'intégralité de l'objet ayant servi à son
appel. Par exemple, on peut avoir besoin d'une méthode
Compar_moyenne qui compare la moyenne de deux élèves (l'instance
paramètre implicite et une instance paramètre explicite) et
retourne l'instance de l'élève ayant la moyenne la plus élevée. On
supposera qu'il n'y a pas d'ex-aequos.
Déclaration de la classe élève
CLASSE
élève
privé
el_nom : chaîne de caractères
el_oral, el_écrit : réel
FONCTION moyenne () : réel
public
PROCEDURE initial (données : nom : chaîne de caractères, or, ec :
réels)
PROCEDURE affich
()
/* Affiche le nom et la moyenne de
l'élève */
FONCTION compar_moyenne (donnée : e : élève) : élève
FCLASSE
Définition de la fonction
compar_moyenne
FONCTION
élève::compar_moyenne (donnée : e: élève) : élève
DEBUT
SI moyenne () > e.moyenne ()
ALORS
RETOURNER moi-même
/* On retourne la valeur de l'objet ayant servi
à l'appel */
SINON
RETOURNER e
FIN
Exemple d'utilisation de compar_moyenne
Soit un tableau tabélève de 5
éléments de classe élève préalablement initialisé (par des appels à
la méthode initial), une variable meilleur de classe élève
et une variable entière i. On souhaite déterminer quel élève
a la moyenne la plus élevée puis afficher le nom et la moyenne de
cet élève :
meilleur ßtabélève[1];
POUR i à 2 A 5
meilleur ß
tabélève[i].compar_moyenne
(meilleur)
FPOUR
AFFICHER "Meilleur élève :
"
meilleur.affich ();
1.2.
Codage en
Java
Java permet au
programmeur de désigner l’objet ayant servi à l'appel de la méthode
par this.
Pour retourner
la valeur du paramètre implicite, il faut donc retourner
this.
Définition de la fonction
compar_moyenne
public eleve
compar_moyenne (eleve e)
{
if (moyenne() >
e.moyenne())
return this
else
return e;
}
Exemple d'utilisation de
compar_moyenne
meilleur
= tabeleve[0];
for (i=1;
i<5; i++)
{
meilleur = tabeleve[i].compar_moyenne (meilleur);
}
System.out.println ("Meilleur
élève : ");
meilleur.affich();
2.
LA SURCHARGE DE
FONCTIONS ET
PROCEDURES
2.1.
Définitions
Une fonction ou procédure est repérée par sa
signature constituée de son nom et du type de chacun de ses
paramètres. Le type du retour pour une fonction n'est pas pris en
compte dans la signature.
Surcharger une fonction ou une procédure
signifie définir plusieurs fonctions ou procédures ayant le même
nom mais des signatures différentes.
Cette surcharge est possible pour des fonctions
ou procédures extérieures à une classe et également pour des
méthodes d'une classe.
2.2. Surcharge de fonctions ou de procédures
extérieures à une classe
2.2.1. Ecriture de
fonctions ou procédures surchargées
On souhaite par exemple pouvoir appeler une
fonction nommée extractch qui permette d'extraire une suite
de caractères d'une chaîne de différentes façons possibles
:
§ en
transmettant la chaîne source, la position de l'élément à partir
duquel il faut effectuer l'extraction et le nombre de caractères à
extraire,
§ en
transmettant la chaîne source, le 1er caractère à partir
duquel il faut effectuer l'extraction et le nombre de caractères à
extraire,
§ en
transmettant la chaîne source et la position de l'élément à partir
duquel il faut effectuer l'extraction, dans ce cas il y a
extraction d'un caractère.
La position transmise est supposée valide (donc
comprise entre 1 et la longueur de la chaîne).
FONCTION extractch (données : ch
: chaîne de caractères, pos, lg : entier) : chaîne de
caractères
DEBUT
RETOURNER SSCHAINE (ch, pos, lg)
FIN
FONCTION extractch (données :
ch:chaîne de caractères, c:caractère, lg:entier) : chaîne de
caractères
VAR pos : entier
DEBUT
pos ß
RANG (ch, c,
1)
SI pos <> 0
ALORS
RETOURNER SSCHAINE
(ch, pos, lg)
SINON
RETOURNER ""
FSI
FIN
FONCTION extractch (données : ch
: chaîne de caractères, pos : entier) : chaîne de
caractères
DEBUT
RETOURNER SSCHAINE (ch, pos, 1)
FIN
2.2.2.
Utilisation
Lors de l'appel à une fonction ou procédure
surchargée, il y a recherche de correspondance entre le type des
paramètres effectifs et celui des paramètres formels.
La correspondance doit être unique c'est-à-dire
qu'un appel doit correspondre à une et une seule fonction ou
procédure.
Instruction
|
Fonction appelée
(1, 2 ou 3)
|
Résultat
|
AFFICHER extractch ("BONJOUR",
2, 3)
|
|
NJO
|
AFFICHER extractch ("BONJOUR",
2)
|
|
N
|
AFFICHER extractch ("BONJOUR",
'N', 3)
|
2
|
NJO
|
AFFICHER extractch ("BONJOUR",
'F', 3)
|
2
|
Chaîne vide
|
2.3. Surcharge de méthodes dans une
classe
Le principe est identique à ce qui a été vu
au §2.2.
Exemple :
Définition d'une classe date avec une
fonction compar surchargée.
CLASSE
date
privé
jj, mm, aaaa : entier
public
PROCEDURE initial (données : j, m, a : entier)
FONCTION compar (donnée : d2 : date) : entier
/* retourne 1 si le param.
implicite > param. explicite, 0 si égalité et –1
sinon. */
FONCTION compar () :
entier
/* retourne 1 si le param.
implicite > date
système, 0 si égalité et –1
sinon.
*/
FCLASSE
PROCEDURE date::initial (données
: j, m, a : entier)
DEBUT
jj ßj
mm ßm
aaaa ßa
FIN
FONCTION date::compar (donnée :
d2 : date) : entier
VAR tot1,
tot2 : entier
DEBUT
tot1 ß
aaaa * 10 ^ 4 + mm * 100 + jj
tot2 ß
d2.aaaa * 10 ^ 4 + d2.mm * 100 + d2.jj
SI tot1 >
tot2
ALORS
RETOURNER 1
SINON
SI tot1 = tot2
ALORS RETOURNER 0
SINON RETOURNER -1
FSI
FSI
FIN
FONCTION date::compar () :
entier
VAR d2 : date
DEBUT
d2.initial (jour_système, mois_système, année_système)
tot1 ß aaaa * 10 ^
4 + mm * 100 + jj
tot2 ß
d2.aaaa * 10 ^ 4 + d2.mm * 100 + d2.jj
SI tot1 >
tot2
ALORS
RETOURNER 1
SINON
SI tot1 = tot2
ALORS RETOURNER 0
SINON RETOURNER -1
FSI
FSI
FIN
Utilisation de la classe date
VAR d1 : date
/* Saisie d'une
1ère date */
AFFICHER "Saisir le jour, le
mois puis l'année"
SAISIR joursaisi,
moissaisi, ansaisi
d1.initial (joursaisi,
moissaisi, ansaisi)
SI d1.compar () =
1
ALORS
AFFICHER "La date saisie est supérieure à la date
système"
SINON
SI d1.compar () = 0
ALORS AFFICHER "La date saisie est la date du
jour"
SINON AFFICHER "La date saisie est inférieure à la date
système"
FSI
FSI
/* Déclaration et
saisie d'une 2ème date puis comparaison avec la
1ère date */
VAR d2 : date
AFFICHER "Saisir le jour, le
mois puis l'année"
SAISIR joursaisi,
moissaisi, ansaisi
d2.initial
(joursaisi, moissaisi, ansaisi)
SI d1.compar (d2) =
1
ALORS
AFFICHER "La 1ère date saisie est supérieure à la
2ème date saisie"
SINON
SI d1.compar (d2) = 0
ALORS AFFICHER "Les 2 dates saisies sont égales"
SINON AFFICHER "La 1 ère date saisie est
inférieure à la 2ème date saisie"
FSI
FSI
2.4. Codage en Java
2.4.1. L'exemple de la
classe date
La classe est nommée MaClasseDate.
Code de la classe
MaClasseDate :
import java.util.GregorianCalendar;
class
MaClasseDate
{
private int jj, mm, aaaa;
public void initial (int j, int m, int a)
{
jj=j;
mm=m;
aaaa=a;
}
public int compar (MaClasseDate d2 )
{
/* retourne 1 si le param. implicite > param.
explicite,
0 si égalité et -1
sinon.
*/
int tot1 = (int)(aaaa * Math.pow(10, 4) + mm * 100 +
jj);
int tot2 = (int)(d2.aaaa * Math.pow(10,4) + d2.mm * 100 +
d2.jj);
if (tot1 > tot2)
return 1 ;
else
{
If (tot1 = = tot2)
return 0
else
return -1;
}
}
public int compar ()
{
/* retourne 1 si le param. implicite > date système,
0 si égalité et -1
sinon.
*/
MaClasseDate d2=new MaClasseDate();
// on récupère la date
système
GregorianCalendar calendar = new
GregorianCalendar();
int jour_système =
calendar.get(GregorianCalendar.DAY_OF_MONTH);
int mois_système=
calendar.get(GregorianCalendar.MONTH)+1;
int année_système=calendar.get(GregorianCalendar.YEAR);
d2.initial (jour_système, mois_système, année_système);
// pow rend un double donc il faut caster explicitement le résultat
en entier
int tot1 =
(int)(aaaa * Math.pow(10, 4) + mm * 100 + jj);
int tot2 = (int)(d2.aaaa * Math.pow(10,4) + d2.mm * 100 +
d2.jj);
if (tot1 > tot2)
return 1 ;
else
{
If (tot1 = = tot2)
return 0
else
return -1;
}
}
}
Code de la classe Prog1date qui utilise
MaClasseDate :
import java.io.*;
class
Prog1date
{
public static void main (String args[]) throws
IOException
{
MaClasseDate d1=new MaClasseDate();
// Saisie d'une 1ère date et
comparaison avec la date système */
int joursaisi = Entrée.entier("Saisir le jour");
int moissaisi = Entrée.entier("Saisir le mois");
int ansaisi = Entrée.entier("Saisir l'année");
d1.initial (joursaisi, moissaisi, ansaisi);
if(d1.compar () == 1)
System.out.println("La date saisie
est supérieure à la date système");
else
if (d1.compar()==0)
System.out.println("La date saisie
est égale à la date système");
else
System.out.println("La date saisie est inférieure à la date
syst.");
}
}
Code de la classe Prog2date qui utilise
MaClasseDate :
import java.io.*;
class
Prog2date
{
public static void main (String args[]) throws
IOException
{
MaClasseDate d1=new MaClasseDate();
MaClasseDate d2=new MaClasseDate();
// Saisie d'une 1ère date
*/
int joursaisi = Entrée.entier("Saisir le jour");
int moissaisi = Entrée.entier("Saisir le mois");
int ansaisi = Entrée.entier("Saisir l'année");
d1.initial (joursaisi, moissaisi, ansaisi);
// Saisie d'une 2ème date */
joursaisi = Entrée.entier("\nSaisir le jour");
moissaisi = Entrée.entier("Saisir le mois");
ansaisi = Entrée.entier("Saisir l'année");
d2.initial (joursaisi, moissaisi, ansaisi);
if(d1.compar (d2) == 1)
System.out.println("La 1ère date est
supérieure à la 2ème date");
else
if (d1.compar(d2)==0)
System.out.println("Les 2 dates sont
égales");
else
System.out.println("La 1ère date est inférieure à la 2ème
date");
}
}
Remarque : le JDK offre bien entendu des classes pour
manipuler les dates, on n'est pas obligé d'écrire ses propres
classes pour traiter les dates comme nous l’avons fait ici à moins
qu'on ait des besoins particuliers.