Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Site Web > PHP > Points particuliers > Abstraction de classes > Lecture du tutoriel

Abstraction de classes

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : ApOpH!s
Note : 15 / 20 (9 votes)
Visualisations : 10 904

Plus d'informations Plus d'informations
Des bases en programmation orientée objet en PHP sont requises pour ce tuto !
Si vous ne les maîtrisez pas, je vous conseille vivement d'aller chercher un tuto traitant de cela sur le site du Zér0.


Si vous avez déjà utilisé la POO (Programmation Orientée Objet) en PHP ou dans n'importe quel autre langage, on vous a sûrement appris que pour utiliser ce "style" de développement, vous deviez instancier une classe et donc créer un objet. Seulement je ne sais pas vous, mais quelque chose me choquait là-dedans. Un des buts de l'instanciation est justement de pouvoir créer plusieurs instances d'une même classe (la définition même d'une instance), sauf que nous n'avons pas toujours besoin d'agir ainsi. :-°

Nous allons donc, dans ce tuto, étudier comment nous passer de l'instanciation, ou plutôt comment l'utiliser à bon escient. Tout d'abord en expliquant plus en détail tout ce bouzin, puis en montrant comment faire.
Sommaire du tutoriel :
Icône du chapitre

Plusieurs instances = inutile ?

Des questions suite à mon introduction ?

Eh mais attends bonhomme, pourquoi diable intancierais-je une classe qui ne sera tout bonnement utilisée qu'une fois ?


T'as tout compris, "bonhomme" ( o_O ) ! Dites-vous bien que créer un objet utilise des ressources, et donc ralentit votre script (plus ou moins visiblement, évidemment) ! A quoi cela sert-il de pouvoir créer deux instances de notre gestionnaire d'erreurs ou de notre template ? Au cours d'une même requête, ces classes ne doivent rationnellement exister qu'en un exemplaire.

Prenons un exemple simple que nous pouvons vivre sur nos PC.
Bien qu'impossible au départ, un plug-in de MSN Messenger permet d'ouvrir deux comptes en même temps, ici, pouvoir ouvrir deux instances de MSN est totalement justifié. Alors qu'au contraire, avoir deux instances de Steam lancées est inutile puisque de toute manière, vous ne pourrez jouer qu'à un jeu à la fois.

Et si j'ai envie d'avoir accès à tout moment à des jeux situés sur deux comptes Steam différents ? :-°


Alors là, tu es en train de bousiller mon exemple ( :colere2: ), et de toute façon les gens ont bien compris ce que j'entendais par là...

Cependant, ne vous méprenez pas : je ne suggère pas ici que l'instanciation des classes est inutile, cela reviendrait à dire que les objets sont inutiles. Je dis seulement que les utiliser - disons "basiquement" - n'est pas toujours la meilleure façon de procéder, la plus optimisée. Heureusement, les génies au quotient intellectuel supérieur y ont pensé avant moi, et ils ont prévu le coup !

Abstraction de classes

Abstraction



Ce à quoi ces messieurs ont pensé porte le doux(loureux) nom d'abstraction de classes. :(

Avant que l'autre #*$£!°^ ne se réveille avec ses questions, je vais anticiper et vous expliquer la chose.

Tout d'abord, il faut savoir que la notion d'abstraction vient avec ses amies les méthodes et propriétés statiques. Finissez vos tubes d'aspirine et écoutez, nous allons déjà laisser la documentation PHP définir ce qu'est une classe abstraite.

Citation : Documentation PHP
PHP 5 introduit les classes (...) abstraites. Il n'est pas autorisé de créer une instance d'une classe définie comme abstraite.


Si vous voulez plus d'informations, s'il vous reste de l'aspirine et si vous avez déjà abordé les principes d'héritage et de visibilité, vous pouvez lire la page qui y est consacrée.


Donc jusque-là, pas d'embrouille : si on déclare une classe comme étant abstraite, on ne pourra pas l'instancier. Voilà ! Notre problème est réglé, je vous souhaite une bonne continuation... :) Nan, ça serait trop infâme de ma part de vous laisser dans le bourbier (surtout qu'une foule en colère, ça fait mal), on va aller un peu plus loin.

Comment diantre crée-t-on une classe abstraite, me demanderez-vous. :euh: Ainsi, vous répondrai-je !

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
abstract class myabstractclass
{
        public $foo;
 
        public function display($str)
        {
                echo $str;
        }
}
?>


En ce qui concerne la définition d'une classe abstraite, seule la première ligne nous intéresse, cela consiste simplement à ajouter le mot-clé abstract devant le mot-clé class. Comme je l'ai dit tout à l'heure, pas d'embrouille ! ;) Essayons d'instancier cette classe...

Code : PHP
1
2
3
<?php
$bar = new myabstractclass;
?>


Et comme attendu, nous voilà gratifiés d'un agréable message d'erreur. o_O

Code : Console
Fatal error: Cannot instantiate abstract class myabstractclass in /srv/www/dev/tuto-abstract/abstract.php on line 12


Accès aux membres depuis l'extérieur



Euh, ouais, bah t'es bien beau toi, mais comment j'vais faire pour accéder à ma propriété et à ma méthode, si aucune variable ne contient un objet ?


Ah, il s'est réveillé ! Ce n'est cependant pas une mauvaise question : d'habitude, quand on instancie une classe, ma variable $bar (voir ci-dessus) aurait contenu mon objet, et j'aurais donc pu accéder à ses membres. Mais ici non, alors comment faire ? Le nom de la classe étant la seule trace que nous ayons de cette structure, nous allons donc l'utiliser. Mais pas comme d'habitude : nous allons utiliser un nouvel opérateur pour remplacer "->" (préparez les tubes) : Paamayim Nekudotayim ! >_<

Et je le trouve où, ce type ?


Sache pour ta gouverne, que Paamayim Nekudotayim signifie "double deux points" en hébreu. Vous vous imaginez donc que ce nouvel opérateur si génial va être "::". Il est appelé opérateur de résolution de portée car basiquement, il permet d'accéder "directement" à n'importe quelle classe qui a été définie, qu'elle ait été instanciée ou non.

Une chose importante à noter avant de faire l'erreur est que contrairement à la "notation objet", il FAUT mettre le symbole du dollar ("$") devant les noms d'attributs.

Code : PHP
1
2
3
4
<?php
$foo?>attribute = 'Bar';
foo::$attribute = 'Bar';
?>


Constructeurs, destructeurs



Une autre chose importante qui devrait couler de source dans vos esprits, c'est le fait que puisque la classe n'est pas instanciée, aucune méthode constructeur (ou destructeur) n'est appelée ; pour en simuler une, vous devez l'appeler explicitement. Généralement, dans mon architecture, j'ai une méthode init() dans chaque classe qui joue le rôle d'un constructeur.

Mettons en oeuvre les deux dernières notions que nous avons apprises.

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
abstract class myabstractclass
{
        public $foo;
        
        public function init()
        {
                self::$foo = 'Hello World! (Parce que j\'en ai marre des foo et des bar)';
        }
        
        public function display($str)
        {
                echo $str;
        }
}
 
myabstractclass::init();
echo myabstractclass::$foo;
?>


Voici ce qui s'affiche ! dit-il dans un cri de victoire.

Code : Console
Fatal error: Access to undeclared static property: myabstractclass::$foo in /srv/www/dev/tuto-abstract/abstract.php on line 8


Staticité (probable néologisme)



Et là je crie "Horreur" ! Que se passe-t-il ? Si vous lisez attentivement le message d'erreur, vous pouvez au moins reconnaître le mot static dont je vous ai parlé tout à l'heure. Littéralement, l'erreur raconte que j'ai essayé d'accéder à un membre qui n'a pas été déclaré comme membre statique ! Mais qu'est-ce que la staticité (je ne sais pas si ce mot existe mais j'aime bien, alors chut !) ?

D'après notre amie la documentation PHP, nous apprenons cela :

Citation : Documentation PHP
Le fait de déclarer des membres ou des méthodes comme statiques vous permet d'y accéder sans avoir besoin d'instancier la classe.


Tu nous avais caché cette information ? Vieux filou, brigand, gredin, malotru ! :o


Disons que je vous ménageais, chaque chose en son temps. Maintenant que nous savons cela, nous pouvons simplement rajouter le mot-clé static entre le mot-clé de visibilité (public, protected ou private) et le nom de l'attribut. Le problème est maintenant réglé.

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
abstract class myabstractclass
{
        public static $foo;
        
        public static  function init()
        {
                self::$foo = 'Hello World! (Parce que j\'en ai marre des foo et des bar)';
        }
        
        public static function display($str)
        {
                echo $str;
        }
}
 
myabstractclass::init();
echo myabstractclass::$foo;
?>


Euh... Tu as aussi déclaré les méthodes comme étant statiques. Elles non plus ne peuvent pas être appelées sans ça ?


Pas exactement ; en réalité, pour cela il faut se dire que la staticité (encore celui-là) n'est pas forcément dépendante de l'abstraction : voyons le tableau ci-dessous pour plus d'éclaircissement (ou de confusion, au choix).

Correspondances abstraction / staticité pour les méthodes
StatiqueNon statique
Classe abstraite Ne peut être appelée que statiquement Ne peut être appelée que statiquement
Classe non abstraite Ne peut être appelée que statiquement Peut être appelée statiquement et non statiquement


Basiquement, l'abstraction oblige à appeler en statique, mais on peut forcer à appeler en statique même en classe non abstraite. Bon, si vos cerveaux sont encore un poil lucides après ce tableau illisible, vous devez vous dire que définir une méthode comme étant statique dans une classe abstraite est totalement inutile... Et vous auriez raison ! Je le mets simplement pour avoir une certaine homogénéité dans mon code. ^^



Accès aux membres intérieurement



Une dernière chose à voir, c'est l'accès aux membres d'une classe depuis cette même classe : $this étant désuet ici puisque la classe n'est pas instanciée, il va falloir trouvée autre chose. C'est ici qu'apparait self ! Il symbolise tout simplement la classe en cours.

Et après on utilise Narabuth Shinoptyies ( :D ) comme tout à l'heure ?


Oui, exactement ; d'ailleurs, vous pouvez remarquer que je l'ai utilisé dans mon code plus haut pour la fonction init(). Il va sans dire que l'utilisation de $this dans une classe abstraite s'ensuivra d'une belle erreur fatale, de la même façon que lorsqu'on essaie de l'instancier.

Code : Console
Fatal error: Using $this when not in object context in /srv/www/dev/tuto-abstract/abstract.php on line 8

Q.C.M.

Quelle est la bonne signature d'une classe abstraite ?
Que va provoquer le code suivant ?

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
abstract class myclass
{
    public $foo;
    public static $bar;
}

$foo = 'Hello World!';
echo myclass::bar;
$bar = new myclass;
?>
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
abstract class myclass
{
      public $foo;
      public static $bar;

      public static function foobar()
      {
      }
}
?>


Comment peuvent, respectivement, être appelés les membres $foo, $bar et foobar() ?

Statistiques de réponses au QCM


Voilà, voilà ! :)

Nous voici arrivés à la fin de notre tuto consacré aux classes abstraites : j'espère que vous avez bien tout compris. En cas de doute, vous pouvez vous référer à la documentation PHP ou poser vos questions en commentaire.

Je tiens néanmoins à rappeler que les classes abstraites ne doivent devenir qu'un semi-automatisme, prenez le temps de réfléchir si oui ou non vos classes doivent être instanciées. Un exemple simple serait celui d'une connexion à une base de données, ici, je fouetterais bien ( :diable: ) ceux qui pensaient déjà à utiliser une classe abstraite pour cela. Vous pouvez très bien avoir plusieurs connexions, à plusieurs serveurs MySQL, par exemple.

Donc, l'abstraction, un produit bon, mais à consommer avec modération !

À vous les studios !
Retour en haut Retour en haut


Créé : le 20/12/2006 à 20:46:15
Modifié : le 09/10/2008 à 19:18:26
Avancement : 100%
Licence : Copie non autorisée

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 86 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.0907s (0.0808s)