Les deux deuxièmes piliers de la POO
Comme je l’ai mentionné dans le premier article de cette série, vous entendrez souvent parler des trois piliers de la programmation orientée objet. Vous pouvez également entendre parler des quatre piliers de la programmation orientée objet.
Et ce n’est pas qu’il y en ait sept au total ou quelque chose comme ça. Au lieu de cela, il s’agit davantage de ce que les gens considèrent comme fondamental pour la POO : y a-t-il trois ou quatre concepts majeurs ?
Vous pouvez déduire de l’article précédent (sans parler du titre), je crois qu’il y en a quatre.
Et dans cet article, je vais couvrir les deux derniers :
- Héritage,
- et polymorphisme
Si vous avez fait n’importe quel type de programmation orientée objet avant de lire cet article, vous avez probablement entendu parler d’au moins l’un d’entre eux.
Quoi qu’il en soit, examinons chacun d’eux plus en détail.
Deux autres piliers de la POO
Avant de sauter dans chacun d’eux, je veux être sûr que vous êtes pris dans ce que nous avons couvert jusqu’à présent.
Un mot sur l’analyse
Je n’insisterai pas sur ce point, mais la raison pour laquelle je parle maintenant des fondamentaux orientés objet est que nous entrons dans une phase différente de ce matériau. Nous avons commencé par couvrir la phase d’ analyse qui comprenait :
- Analyse, partie 1
- Analyse, partie 2
- Comprendre les attentes des clients
- Énoncé des travaux
- Termes et conditions
Maintenant au développement
Et maintenant nous entrons dans la phase de développement . Certains peuvent appeler cela les fondamentaux (mais je suis content que vous ne puissiez pas faire un bon développement sans les fondamentaux, donc il y a ça (.
Si vous n’avez pas lu l’article précédent, je vous recommande de le faire avant de continuer car il couvre les concepts d’abstraction, d’encapsulation et son lien avec WordPress.
3 Héritage
Le concept d’héritage est assez facile à suivre. Autrement dit, une classe peut hériter des attributs d’une autre classe. Je vais en donner quelques exemples dans un instant, mais permettez-moi de fournir une définition de travail aux fins de cet article :
L’héritage fait référence à l’idée qu’une classe, bien qu’elle ait sa propre implémentation, hérite littéralement des propriétés, des fonctions et de l’implémentation générale d’une classe parent.
Exemple 1 : un document
En termes très simples, disons que vous avez une classe appelée Document et qu’un document a un titre et un contenu. Ensuite, il y a une sous-classe de document qui a des attributs pour une date et une heure. Nous pourrions appeler cela un PostDocument ou un PageDocument.
Autrement dit, le PageDocument hérite des propriétés et des attributs de Document tout en y ajoutant sa propre implémentation. Avoir du sens ?
Sinon, ne vous inquiétez pas. Il ne "clique" pas toujours au début, alors regardons un autre exemple.
Exemple 2 : un message
Disons que nous avons une classe Message. Un message a généralement deux propriétés :
- 1 Un expéditeur,
- 2 Un destinataire.
Il est juste de dire qu’il existe différents types de messages, n’est-ce pas ? Autrement dit, nous avons peut-être un EmailMessage ou peut-être un TextMessage.
Un EmailMessage a toujours un expéditeur et a toujours un destinataire, mais il a tellement plus, n’est-ce pas ? Il a des choses comme :
- une ligne d’objet,
- une pièce jointe facultative,
- un autre ensemble d’expéditeurs auxquels il est envoyé,
- prise en charge de la copie d’autres personnes vers le message publiquement ou en privé,
- et beaucoup plus.
Un TextMessage, d’autre part, n’aura pas nécessairement tout ce qui précède. Supposons que nous parlons d’un message SMS de base (par rapport à un message texte enrichi dans quelque chose comme Hangouts, Telegram, iMessage ou tout ce qui existe).
Cette classe va :
- être lié à un numéro de téléphone,
- peut inclure un groupe d’autres destinataires qui sont tous publics,
- un opérateur (c’est-à-dire un fournisseur de téléphonie mobile),
- un nombre maximum de caractères qu’il peut contenir
- la possibilité de diviser un seul message en plusieurs messages si le nombre maximum de caractères dépasse un certain nombre de caractères.
Mais cela soulève toujours des questions sur les propriétés et les méthodes (ou, plus généralement, la mise en œuvre, n’est-ce pas ?)
Un mot sur la mise en œuvre
En matière de programmation orientée objet, nous avons ce que nous appelons des modificateurs d’accès. Peut-être les avez-vous lus ailleurs, appelés, disons, modificateurs de visibilité ou quelque chose comme ça.
C’est tout pareil.
En bref, ces modificateurs peuvent être définis comme :
Mots-clés qui contrôlent ce que les autres classes ont accès aux informations disponibles.
Heureusement, cette partie est simple à comprendre :
- les propriétés et fonctions privées ne sont accessibles qu’à la classe dans laquelle elles sont définies. Cela signifie que PostDocument ne peut rien utiliser dans Document marqué comme privé. À toutes fins utiles, PostDocument n’est même pas au courant de l’existence de ces informations.
- les propriétés et fonctions protégées sont accessibles à la classe dans laquelle elles sont définies et à toute classe qui en est la descendante. Autrement dit, toute classe qui hérite des données de la classe de base ou de la classe parent y a accès. Ainsi, contrairement aux détails d’implémentation privés, le PostDocument peut accéder aux informations de Document s’il est marqué comme protégé.
- les propriétés et les fonctions publiques sont accessibles à tous. Cela n’a rien à voir avec l’héritage, vraiment, mais plutôt avec l’encapsulation, le cas échéant. Au lieu de cela, il s’agit de décider à quoi nous voulons que les autres objets accèdent.
Alors, comment la mise en œuvre est-elle gérée? Cela varie d’une langue à l’autre, mais PHP ne prend pas en charge ce qu’on appelle "l’héritage multiple". En termes simples, une classe donnée en PHP ne peut hériter (ou étendre) qu’une seule autre classe. Pas plusieurs classes (certaines langues le supportent).
Lorsque vous étendez une classe, la sous-classe hérite de toutes les méthodes publiques et protégées de la classe parent. À moins qu’une classe ne remplace ces méthodes, elles conserveront leur fonctionnalité d’origine.
Dans notre exemple, nous ne pouvons pas introduire une autre classe telle que WrittenDocument qui hérite de PageDocument ainsi que de PostDocument. C’est soit l’un soit l’autre. Et il convient de noter que s’il hérite de PostDocument, il hérite également des informations de Document car il s’agit d’une sous-classe d’une sous-classe d’une classe.
4 Polymorphisme
Maintenant que nous avons une définition de base de l’héritage en place, nous pouvons parler de polymorphisme. La bonne nouvelle est qu’il s’agit d’un mot large et étrange pour un concept très simple.
La mauvaise nouvelle est que nous n’avons pas parlé d’interfaces ou de classes abstraites. Celles-ci arrivent, mais elles sont considérées comme faisant partie des quatre piliers, alors ne vous en souciez pas pour le moment.
Pensez-y plutôt :
Le polymorphisme nous permet de faire référence à une classe d’un type lorsqu’elle peut être déclarée comme un autre type.
Cela peut encore prêter à confusion, mais souvenez-vous de notre exemple de message ci-dessus ? Nous pouvons instancier une classe SMSMessage qui étend la classe Message, puis appeler certaines méthodes sur celle-ci.
Le SMSMessage peut avoir une méthode que la classe Message a. Et si la classe a été instanciée en tant qu’instance de la classe SMSMessage, elle appellera cette méthode. De même, s’il n’a pas de méthode mais que sa classe parent, Message, l’a, alors il appellera cette méthode.
Parfois, il est plus facile de comprendre cela dans le code, alors faisons cela.
Commençons par définir notre classe Message :
<?php
class Message
{
public function send()
{
echo "This message is sent from the Message class.n";
}
public function receive()
{
echo "This message was received from the Message class.n";
}
}
Définissons ensuite notre classe SMSMessage. Notez qu’il n’a pas de fonction receive(). Ce sera important momentanément :
<?php
class SMSMessage extends Message
{
public function send()
{
echo "This message is sent from the SMSMessage class.n";
}
}
Maintenant, instancions notre classe Message et appelons quelques méthodes :
<?php
$message = new Message();
$message->send();
$message->receive();
Et faisons de même en utilisant la classe SMSMessage :
<?php
$message = new SMSMessage();
$message->send();
$message->receive();
Si vous voulez le script complet, vous pouvez le voir ici, le télécharger et l’exécuter localement.
Héritage, polymorphisme et WordPress
Voici ce qu’il faut retenir (et nous l’explorerons davantage lorsque nous aborderons les interfaces et les classes abstraites) : lorsqu’une classe étend une autre classe et qu’elle n’a pas les détails d’implémentation de sa classe parent, l’implémentation du parent sera utilisée.
Une autre façon de penser est de «remonter la chaîne de commandement ». Cela commencera par la classe la plus basse de ce que nous avons créé. Dans notre exemple ci-dessus, c’est le SMSMessage. S’il ne le trouve pas, il remontera dans la classe qu’il étend. (Et s’il ne le trouve pas là et que cette classe étend une classe, il essaiera là.)
Toute la chose polymorphe est la suivante: nous avons instancié une classe d’un type, SMSMessage, mais elle utilise l’implémentation d’une classe d’un autre type (dont elle hérite, oui, mais c’est quand même différent).
Cours d’écriture sur WordPress
Enfin, j’aimerais vous laisser avec ceci : j’ai mentionné quelque chose de similaire à cela dans le post précédent, mais je veux le répéter ici.
Quel que soit le nombre de ces concepts utilisés par le cœur de WordPress, cela n’a pas d’importance car nous pouvons écrire du code orienté objet de haute qualité sur WordPress qui interagit avec WordPress et qui fonctionne bien avec WordPress (et d’autres codes tiers – pas toujours, mais plusieurs fois).
Quoi de neuf ensuite ?
Ensuite, nous examinerons les interfaces et les abstractions.
Celles-ci sont toujours fondamentales pour la programmation orientée objet, mais si vous avez compris les deux articles précédents, vous êtes prêt pour une solide expérience avec les concepts à venir.
Et si ce n’est pas le cas, ne vous inquiétez pas! Vous pouvez toujours en parler dans les commentaires ou nous pouvons en discuter davantage par e-mail.