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

            FSI

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)

1

NJO

AFFICHER extractch ("BONJOUR", 2)

3

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.