Classes et méthodes abstraites. Classes et méthodes finales
#1 Classes abstraites
Pour faire simple, une classe abstraite est une classe qui ne peut pas être instanciée. On ne peut donc pas l'utiliser tel quel. Il faut impérativement créer une classe fille qui hérite de la classe abstraite, et ensuite instancier la classe fille. Ainsi, on peut utiliser le tout.
Ci-dessous, un exemple avec une classe abstraite. Le nom de la classe doit être préfixé par abstract si vous voulez respecter les PSRs. Ce qui donne pour cet exemple AbstractDataTop
.
La classe AbstractDataTop
contient un algorithme. Elle ne contient pas de données. La donnée doit être précisée dans chaque classe fille DataFaq
ou DataQR
. C'est une forme de généricité (* à condition de pousser le raisonnement jusqu'au bout et de couvrir toutes les opérations sur la table. Ici, c'est un peu léger) 😏.
La classe AbstractDataTop
contient la méthode findAll
qui fait la liste des enregistrements d'une table de base de données. Peu importe la table. Le nom de la table $table
est une propriété protégée de la classe AbstractDataTop
qui est surchargée dans chaque classe fille.
Vous pouvez télécharger le sql pour créer la database et les codes php de ce tutoriel ici.
Si vous avez besoin d'une classe abstraite, sachez qu'il n'est absolument pas obligatoire qu'elle contienne une méthode abstraite. Ca n'a rien à voir.
Ci-dessous, j'ai ajouté un new AbstractDataTop
dans index.php
pour instancier la classe abstraire et j'ai déclenché une exception.
#2 Méthodes abstraites
Dans l'exemple ci-dessous, je déclare une méthode abstraite myPrint
. Je le fais en deux étapes.
- La première étape dans la classe mère
AbstractDataTop
, je déclare la fonction sans le corps de la fonction. - La deuxième étape dans la classe fille
DataFaq
, je reprends, tel quel, la déclaration qui est dans la classe mère et j'implémente le corps de la fonction.
Ce que je fais dans la classe mère, c'est que j'impose la spécification de la fonction. J'impose sa visibilité, son nom, le type de chaque paramètre et le type de la valeur de retour. On appelle cela la signature. En fait, la classe mère dit, si une classe veut être ma classe fille, hé bien, elle doit développer cette méthode en respectant la signature que je lui impose. Par contre, ma classe fille peut implémenter la méthode telle qu'elle le veut. C'est un contrat entre la mère et la fille. Par exemple ici, dans le myPrint
de DataFaq
, je vais mettre un var_dump
et dans le myPrint
de DataQr
, je vais mettre un print_r
.
Dans le cas général, vous devez respecter ceci :
- Si vous avez besoin d'une méthode abstraite, alors la classe mère qui contient la signature doit être abstraite.
- Dans la classe abstraite, Le mot réservé abstract doit être placé devant la déclaration de visibilité de la méthode si vous voulez respecter les PSRs.
Comprenez bien que vous devez implémenter la signature si vous voulez hériter de la classe abstraite. Ce n'est pas une option. Sinon, vous aurez une erreur.
Donc ci-dessous, j'implémente la méthode myPrint
dans la classe DataQr
.
Ci-dessous, l'appel de myPrint
dans les deux classes.
#3 Classes et méthodes finales
Pour l'instant, je peux dériver la classe dataFaq
. Je le fais et dans la classe NewData
, je crée une nouvelle surcharge de myPrint
. J'exécute et ça fonctionne correctement.
Maintenant, si je veux interdire la surcharge du myPrint
de DataFaq
dans NewData
, il me suffit de déclarer la méthode myPrint
finale dans DataFaq
.
Si vous voulez être conforme aux PSRs il vous faut mettre le final avant la déclaration de visibilité.
Ci-dessous, je veux aller plus loin. J'ajoute final
devant la déclaration de la classe DataFaq
. Dans ces conditions, DataFaq
ne peut plus avoir de fille.