Polymorphisme et PHP5

Le polymorphisme est un concept majeur de la Programmation Orientée Objet (POO). Des langages mûrs tels que C++ ou JAVA intègrent ce concept de manière native. PHP5 permet également d’intégrer le polymorphisme dans le développement PHP.

Qu’est-ce que le polymorphisme?

Son principe réside dans son nom : [poly-] signifie beaucoup et [-morphisme] signifie formes, états. Ainsi, intégrer le polymorphisme dans la programmation permet au développeur d’initialiser un seul objet qui se comportera différemment selon son type. Pratiquement parlant, le développeur écrit une classe de base qui définit les attributs de l’objet et autant de sous-classes que de comportements différents de l’objet seront nécessaires.

Voici un exemple simple de design polymorphique dans le cadre d’un objet véhicule. La classe véhicule a pour attributs des informations qui valent pour tout type de véhicule : marque, date d’achat, prix d’achat :

Class Vehicule {

 

protected $marque;
protected $date_achat;
protected $prix_achat;
public function __construct($marque,$date_achat,$prix_achat) {
$this->marque = $marque;
$this->date_achat = $date_achat;
$this->prix_achat = $prix_achat;
}

}

On peut ensuite créer la classe avion et la classe voiture héritant de la classe véhicule :

Class Voiture Extends Vehicule {

private $cylindree;
private $km;
public function __construct($array) {
parent::__construct($array["marque"],$array["date_achat"],$array["prix_achat"]);
$this->cylindree = $array["cylindree"];
$this->km = $array["km"];
}
}

Class Avion Extends Vehicule {

private $type;
private $heures_vol;
public function __construct($array) {
parent::__construct($array["marque"],$array["date_achat"],$array["prix_achat"]);
$this->type = $array["type"];
$this->heures_vol = $array["heures_vol"];
}

}

Structurer vos classes de cette manière permet de rendre votre programmation orientée objet plus abstraite, et donc plus flexible. Changer un type d’objet particulier après production sera plus aisé et plus stable.

Objets sans design polymorphique

Créer une classe de génération de champs de formulaire sans polymorphisme :

<?php
class Form {
public function genInput($type,$name,$value) {
SWITCH($type) {
Case »text »:
print « <input type=\ »text\ » name=\ »".$name. »\ » value=\ »".$value. »\ » />\r\n »;
break;
Case »textarea »:
print « <textarea name=\ »".$name. »\ »> ».$value. »</textarea>\r\n »;
break;
}
}
}
$form = new Form(); //initialisation de l’objet formulaire
$form->genInput(« text », »field1″, »Lorem ipsum… »); //affiche <input type= »text » name= »field1″ value= »Lorem ipsum… » />
$form->genInput(« textarea », »field2″, »Lorem ipsum… »); //affiche <textarea name= »field2″>Lorem ipsum…</textarea>
?>

Objets avec design polymorphique

Pour qu’un objet puisse revêtir plusieurs formes, qu’il s’agisse d’un champ texte ou d’un champ textarea, nous devons rendre notre classe plus abstraite.
Nous allons donc créer une interface, une classe abstraite et quelques sous-classes (selon le type de champ).
L’interface définira les fonctions que l’objet appellera sans définir ce que ces fonctions feront. L’interface ne définira aucune des fonctionnalités de ces méthodes, elle se contente de les nommer. Chaque sous-classe devra comporter la définition de la méthode genInput().

//INTERFACE
interface Form {

public function genInput();

}

Une classe abstraite est une classe qui nous n’implémentons que partiellement. Elle contient les méthodes (fonctions) abstraites qui offrent des fonctionnalités communes. Le reste des autres fonctioannlités sera défini dans les sous-classes.
//ABSTRACT CLASS
abstract class Input {
protected $name;
protected $value;
public function __construct($name,$value) {
$this->name = $name;
$this->value = $value;
}
}
Puis les classes dérivées appelleront la méthode définie dans la classe abstraite (parent::__construct()) et la méthode nommée dans l’interface (genInput()) :
//TEXT & PASSWORD & HIDDEN INPUT
class Text extends Input implements Form {
private $type;
private $size;
public function __construct($array) {
parent::__construct($array["name"],$array["value"]);
$this->type = $array["type"];
$this->size = $array["size"];
}
public function genInput() {
return « <input type=\ »".$this->type. »\ » name=\ »".$this->name. »\ » value=\ »".$this->value. »\ » size=\ »".$this->size. »\ » />\r\n »;
}
}
//TEXTAREA INPUT
class Textarea extends Input implements Form {
private $cols;
private $rows;
public function __construct($array) {
parent::__construct($array["name"],$array["value"]);
$this->cols = $array["cols"];
$this->rows = $array["rows"];
}
public function genInput() {
return « <textarea name=\ »".$this->name. »\ » cols=\ »".$this->cols. »\ » rows=\ »".$this->rows. »\ »> ».$this->value. »</textarea>\r\n »;
}
}
Voici comment créer un champ texte :
$object = new Text(array(« type »=> »text », »name »=> »form_id », »value »=>$item, »size »=>20));
$hidden = $object->genInput();
Générer un champ textarea ressemble à ceci :
$object = new Textarea(array(« name »=> »form_txta », »value »=>$item , »cols »=>20 , »rows »=>5));
$textarea = $object->genInput();
Webliography :

Abstract classes and interfaces
Devshed polymorphism in PHP5 article
PHP5 Tutorial : Abstract classes and Interfaces
PHP5 OOP abstract classes & interfaces