Une classe n'est rien d'autre qu'un ensemble de fonctions et de variables. Nous allons créer une Classe Bistrot, qui sera composée de 2 fonctions simples : ServirABoire et MettreLaTable. Nous "ouvrirons" ensuite un nouveau bistrot : $CafeDesAmis = new Bistrot;, et depuis cette "variable composée", nous allons appeler la fonction ServirABoire et MettreLaTable : $CafeDesAmis->ServirABoire(); et $CafeDesAmis->MettreLaTable();.
class
Bistrot
{
function ServirABoire()
{
echo "Je sers à boire";
}
function MettreLaTable()
{
echo "Je met la table";
}
}
$CafeDesAmis = new Bistrot;
$CafeDesAmis->ServirABoire();
$CafeDesAmis->MettreLaTable();
Lors de la ligne $CafeDesAmis = new Bistrot;, nous disons que nous instancions la classe Bistrot : nous créons une instance de cette classe. Nous pouvons avoir plusieurs instances d'une même classe :
class
Bistrot
{
function ServirABoire()
{
echo "Je sers à boire";
}
}
$CafeDesAmis = new Bistrot;
$AuSoleilLevant = new Bistrot;
$CafeDesAmis->ServirABoire();
$AuSoleilLevant->ServirABoire();
class Bistrot
{
var $NombreClient;
}
$MonCafe = new Bistrot;
$MonCafe->$NombreClient++;
echo $MonCafe->$NombreClient;
L'intérêt des classes par rapport aux fonctions simples, est que les variables gardent automatiquement leurs valeurs dans les instances respectives. Je m'explique par un exemple simple :
class Bistrot
{
var $NomBreClient;
}
$CafeDeLaGare = new Bistrot;
$SoleilLevant = new Bistrot;
$CafeDeLaGare->$NombreClient+=5;
$SoleilLevant->$NombreClient+=2;
$CafeDeLaGare->$NombreClient++;
echo $CafeDeLaGare->$NombreClient; // Affiche 6
echo $SoleilLevant->$NombreClient; // Affiche 2
L'usage veut qu'un passe plutôt par une fonction que directement par les variables. Par exemple, on pourrait imaginer une fonction pour ajouter un client, et pour retirer un client :
class Bistrot
{
var $NombreClient;
function AjouteClient()
{
$NombreClient++
}
function EnleveClient()
{
$NombreClient--
}
}
$CafeDeLaGare = new Bistrot;
$CafeDeLaGare->AjouteClient();
$CafeDeLaGare->AjouteClient();
$CafeDeLaGare->EnleveClient();
echo $CafeDeLaGare->$NombreClient // devrait afficher 1
... Mais en fait n'affiche rien du tout (comme si $NombreClient ne valait rien). En fait, les $NombreClient utilisés dans les 2 fonctions sont considérées comme 2 variables locales distinctes $NombreClient et $NombreClient, bien qu'elles aient le même nom ! Ce qui fait que la variable globale $NombreClient de la classe n'est jamais incrémentée !
A contrario, l'exemple précédant celui-ci fonctionnait très bien, puisqu'on accédait directement à la variable globale de la classe $NombreClient
Pour préciser que nous désirons bien utiliser la variable globale $NombreClient, nous allons utiliser le mot-clé this, qui veut dire "Celle ci", "la variable globale de cette classe", comme ceci :
class Bistrot
{
var $NombreClient;
function AjouteClient()
{
$this->$NombreClient++;
}
function EnleveClient()
{
$this->$NombreClient--;
}
}
$CafeDeLaGare = new Bistrot;
$CafeDeLaGare->AjouteClient();
$CafeDeLaGare->AjouteClient();
$CafeDeLaGare->EnleveClient();
echo $CafeDeLaGare->$NombreClient //
Affiche vraiment 1 cette fois
Le constructeur est simplement une fonction qui possède le même nom que la classe elle-même. Le constructeur prend en quelque sorte la responsabilité de l'initialisatioon de la classe. Par exemple, admettons que d'entrée, le nombre de clients est = à 5, nous aurions une fonction Bistrot dans la classe Bistrot. Cette fonction est automatiquement appelée lors de l'appel à New Bistrot :
class Bistrot
{
var $NombreClient;
function Bistrot()
{
$this->$NombreClient = 5;
}
}
$CafeDeLaGare = new Bistrot; // Et appel
implicite à Bistrot()
echo $CafeDeLaGare->$NombreClient // Affiche 5
Il est très possible de définir une classe, avec ses propres variables et fonctions, et ensuite constater qu'on a besoin d'une classe un peu similaire, mais avec des trucs en plus. Dans l'exemple qui suit, nous avons une classe Bistrot, et nous avons fait hérité les variables et fonctions (appelées méthodes dans le contexte d'une classe) à une deuxième classe que nous appellerons Restaurant :
class Bistrot
{
function JaiSoif()
{
echo "Vous désirez boire un verre";
}
}
class Restaurant extends Bistrot
{
function JaiFaim()
{
echo "Vous désirez le plat du jour";
}
}
$CafeDeLaGare = new Bistrot;
$ChezLucullus = new Restaurant;
$CafeDeLaGare->JaiSoif();
$ChezLucullus->JaiSoif();
$ChezLucullus->JaiFaim();
$CafeDeLaGare->JaiFaim();
// ERREUR, évidemment !
Avec PHP, il n'est pas possible de créer une classe dérivée
de 2 classes-mères différentes. Par exemple, si nous avons une
classe Bistrot et une classe BoiteDeNuit, il n'est pas possible d'écrire
un truc du style :
Class CentreDeLoisirs extends Bistrot, BoiteDeNuit
!
class Bistrot
{
function JaiSoif()
{
echo "Vous désirez boire un verre";
}
}
class Restaurant
extends Bistrot
{
function JaiFaim()
{
echo "Vous désirez le plat du jour";
}
}
class Hotel extends Restaurant
{
function JaiSommeil()
{
echo "Vous désirez dormir";
}
}
$LeBonRepos = new Hotel;
$LeBonRepos->JaiFaim();
$LeBonRepos->JaiSoif();
$LeBonRepos->JaiSommeil();
Que se passe-t-il si une classe possède une fonction de même nom que la classe parente ? Une erreur ? Pas du tout ! PHP s'en sort très bien, comme ceci :
class Bistrot
{
function JaiSoif()
{
echo "Tiens, vla une bière !";
}
}
class Restaurant
extends Bistrot
{
function JaiSoif()
{
echo "Voici un petit apéritif";
}
function JaiFaim()
{
echo "Voici votre plat du jour"
}
}
$ChezLucullus = new Restaurant;
$CafeDeLaGare = new Bistrot;
$ChezLucullus->JaiSoif(); // petit apéritif
$CafeDeLaGare->JaiSoif(); // une bière
Bien entendu, l'usage des variables suit la même règle.
Nous avons vu qu'une fonction qui porte le nom de la classe est automatiquement exécutée lors de l'instanciation de la classe en question avec new. Bien. Ensuite, nous avons vu que nous pouvons créer de nouvelles classes en les dérivant de classes parentes en utilisant l'héritage et le mot-clé extends. Parfait. Considérons maintenant cet exemple :
class Bistrot
{
function Bistrot()
{
echo "Je construit le Bistrot";
}
}
class Restaurant extends Bistrot
{
}
$ChezLucullus = new Restaurant;
Pensez-vous que lors de l'instanciation $ChezLucullus = new Restaurant;, le constructeur function Bistrot() sera exécuté ?
La réponse est OUI avec PHP4 et NON avec PHP3. Fallait le savoir !
class Bistrot
{
function Bistrot()
{
echo "Je construis le Bistrot";
}
function Restaurant()
{
echo "Je construis le restaurant";
}
}
class Restaurant extends Bistrot
{
}
$ChezLucullus = new Restaurant;
En fait, lors de l'instanciation de $CafeDeLaGare = new Bistrot;, le constructeur function Bistrot() va s'exécuter automatiquement. Et lors de l'instanciation $ChezLucullus = new Restaurant;, il va automatiquement exécuter function Restaurant()de la classe Bistrot, qu'il va considérer comme son constructeur !!!
Bon, comme on pourrait s'y attendre, le cas suivant n'exécute QUE le constructeur de la classe Restaurant :
class Bistrot
{
function Restaurant() // n'est pas exécutée
{
echo "Je construis le restaurant depuis le Bistrot";
}
}
class Restaurant extends Bistrot
{
function Restaurant ()
{
echo "Je construit le restaurant depuis le restaurant";
}
}
$ChezLucullus = new Restaurant; // "Je
construit le restaurant depuis le restaurant"
J'utilise PHP4, et c'est effectivement le résultat que j'obtiens. Etrangement d'ailleurs, car dans l'aide de PHP, il est très nettement écrit : "'Un constructeur est une classe de même nom, définit dans la classe elle-même", ce qui veut bien dire que normalement, un constructeur ne peut pas se trouver dans la classe parente, me semble-t-il ...
Tout simplement en faisant ceci :
$this->nom_de_la_methode_parente();
---