Classes, encapsulation et composition
Les classes
Une classe, c'est ce qui défini la recette d'un objet en PHP. En gros cela nous dit : voilà comment ça s'appelle, voilà ce qu'il y a dedans, voilà ce que ça fait.
Prenons une classe toute simple :
Notre User a un nom et peut se présenter.
this
Le mot clé $this est spécifique à la POO. Lorsque vous êtes à l'intérieur d'une classe (donc dans son fichier), il sert à appeler un attribut ou une méthode de la classe définie dans ce fichier.
Dans l'exemple de la classe User ci-dessus, il appelle l'attribut name. Il ne peut pas être utilisé en dehors du fichier de définition d'une classe.
Le constructeur
Dans notre classe User : nous avons défini notre classe, nous savons qu'un User a un nom, et qu'il peut se présenter.
Il nous faut un moyen de "remplir" ce nom. Il y a deux façons de le faire :
fournir une méthode permettant de modifier le nom, appellée un setter
permettre de lui donner un nom dès qu'on la créée, avec un constructeur
Lorsque l'on va instancier la classe, nous allons lui passer un argument avec la valeur du name, qui sera automatiquement stockée dans l'attribut de la classe.
💡 Avant PHP 8, nous devions écrire cette assignation $this->name = $name dans le corps du constructeur (entre les accolades) mais maintenant le langage le fait pour nous si on lui précise un modificateur de visibilité (public, private ou protected).
Instance et classe
Dans votre fichier User.php vous avez défini la classe User c'est une recette qui définit ce qu'est un User, ce qu'il contient et ce qu'il peut faire. Mais les gourmand-e-s le savent : ça n'est pas parce qu'on a la recette qu'on a un gâteau 🧁.
Dans cette métaphore, la classe est la recette et le gâteau va s'appeler une instance de classe.
Pour créer une variable qui soit une instance de la classe User on dit qu'on va instancier un User. La syntaxe est la suivante :
Écrire new User("Mari") cela demande à appeler le constructeur de la classe User en lui passant le paramètre "Mari" qui ira donc remplir son attribut name. Je peux ensuite appeler ses méthodes en utilisant ->.
L'encapsulation
Un peu plus tôt dans le cours, j'ai fait miroiter de vous expliquer à quoi correspondait le mot clé public: le moment est venu.
Un autre principe fondamental de la POO c'est l'encapsulation. Chacun a un rôle et gêre ses petites affaires. Pour éviter les erreurs et le fouillis, on règlemente l'accès aux méthodes et aux attributs de la classe.
Pour règlementer ces accès, on utilise deux mots clés : public et private. Il en existe un troisième, protected que nous verrons au moment d'aborder l'héritage.
public
Si un attribut ou une méthode est public on peut y accéder depuis l'extérieur de la classe (l'extérieur de son fichier). C'est ce qui permet de faire $user->sePresenter() avec le User. La méthode sePresenter est public.
private
Si un attribut ou une méthode est private, on ne peut y accéder que depuis l'intérieur de la classe (dans son fichier donc). C'est ce qui permet d'éviter les erreurs et les effets de bord et de contrôler ce qui se passe dans la classe.
Bonnes pratiques
Pour les attributs, c'est assez simples : ils sont toujours private. Dans mes exemples précédents, ils étaient public pour pouvoir fonctionner directement si vous copiez-collez le code.
Pour les méthodes, cela dépend, mais en règle générale, elles sont public sauf si vous n'avez jamais besoin de les appeler depuis l'extérieur de la classe.
Les getters et setters
Mais si tous mes attributs sont private, ils me servent à quoi si je ne peux jamais y accéder ?
En fait, il va falloir créer des méthodes, spécifiquement pour pouvoir les lire et les modifiers.
Les méthodes de lecteurs sont appellées des getters et les méthodes de modification des setters. Les getters et les setters sont public.
Un getter aura le nom getMonAttribut et un setter le nom setMonAttribut.
Analyse d'une classe
Essayez de me décrire la classe suivante :
Précisions sur les attributs
Dans une classe, les attributs peuvent avoir une valeur par défaut :
et peuvent être null:
La composition
Le principe de la composition est assez simple : une classe peut en contenir une autre.
En effet, l'attribut d'une classe peut être une autre classe.
Exemple : User et Address
Address.php
User.php
index.php