PHP : petit exemple mêlant type-hint, abstraction et héritage.

Nous allons écrire un tout petit snippet pour mettre en évidence des concepts de base de la programmation orientée objet. Le but ici est d’utiliser l’abstraction, l’héritage, le typage (type-hint) et le principe de substitution de Liskov. Le tronc de notre arbre d’héritage est ici la classe abstraite Animal; elle ne possède qu’une seule fonction membre : communiquer.

Pourquoi communiquer est une fonction abstraite (un prototype, donc) dans Animal ? Tout simplement parce qu’un animal ne communique pas forcément comme un autre. Nous déléguons ici la responsabilité de l’implémentation de cette méthode aux classes filles d’Animal.

Nous avons ensuite deux classes concrètes Chameau et Belette qui elles détaillent la manière dont nos animaux communiquent: dès lors qu’elles dérivent Animal, elles sont tenues d’implémenter la méthode communiquer, ce qu’elles font, chacune à leur manière (le chameau blatère tandis que la belette…belote, et oui !).

Nous avons finalement une classe Communicateur, dont une variable d’instance privée et nommée _animal va contenir l’instance d’Animal sur laquelle nous allons opérer. Notez que nous avons forcé le type de paramètre en disant « Nous exigeons une instance de la classe Animal » dans le constructeur de cette classe. C’est une bonne chose que de ne pas accepter n’importe quoi

Souvenez-vous toujours de cette phrase de feu-Jon Postel :

Be liberal in what you accept, and conservative in what you send

Vous restez libéral dans ce que vous acceptez (tout en étant il faut le dire un peu conservateur aussi, puisque vous contraignez le type malgré tout), vous acceptez tout ce qui est un Animal : donc, tout ce qui dans l’arbre d’héritage se situe dans les branches (et les feuilles) partant du tronc qui est Animal.


abstract class Animal {
    abstract public function communiquer();
}

class Chameau extends Animal{
     public function communiquer() {
         echo "Je blatère", PHP_EOL;
     }
}

class Belette extends Animal{
    public function communiquer() {
        echo "Je belote", PHP_EOL;
    }
}

class Communicateur {

    private $_animal;

    public function __construct(Animal $animal) {
        $this->_animal = $animal;
    }

    public function faireCommuniquer() {
       $this->_animal->communiquer();
    }
}

$communicateur = new Communicateur(new Belette);
$communicateur->faireCommuniquer();

$communicateur = new Communicateur(new Chameau);
$communicateur->faireCommuniquer();

Une instance de la classe Communicateur a donc en composition un objet du super-type Animal. La seule méthode de cette classe est faireCommuniquer, qui se base sur la méthode communiquer de l’instance d’Animal (et classes filles) en composition. Lorsqu’on appelle faireCommuniquer de Communicateur, on appelle en fait en coulisses Animal->communiquer.

Nous garantissons que quelque soit l’instance de la sous-classe d’Animal passée en paramètre du constructeur de Communicateur, le comportement de Communicateur sera le même…Cela ne vous rappelle pas un certain principe de substitution de Liskov ?

chameau

Source photo : 20 Minutes

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.