OVH Cloud OVH Cloud

changement de prototype dans une classe derive e PHP5

1 réponse
Avatar
Eric Daspet
Voilà, l'équipe de dev PHP a fait un truc qui va faire parler un bon
moment. Désormais le code suivant génère une erreur (sisi, dans le futur
PHP5) :

class maClasse {
function maFonction( $monArgument ) {
// ... instructions
}
}

class maDerivee {
function maFonction( $monArgument, $deuxiemeArgument ) {
// ... instructions
}
}


Ce type de changement a été discuté pour les interfaces :

interface monInterface {
function maFunction( $monArgument ) ;
}

class maClasse {
function maFonction( $monArgument ) {
// ... instructions
}
}

Il a été considéré que si on autorisait une classe dérivée à redéfinir
le prototype, alors l'interface n'était plus assurée. Il fallait forcer
les classes dérivées à accepter aussi les appels faits avec le prototype
de l'interface. Du coup on peut rajouter des arguments supplémentaires,
mais uniquement si ils ont une valeur par défaut (c'est à dire si on
autorise à ne pas les utiliser).

Le problème c'est qu'ils ont fait la même relation d'identité pour les
classes dérivées même sans interface, considérant que si on change le
prototype, maDérivée ne "sera" plus une classe de type maClasse et que
tous les objets de type maClasse (même spécialisés) devraient accepter
les prototypes de maClasse.

Il n'est donc simplement plus possible de dériver une classe en lui
donnant des spécificités fortes. On ne pourra plus réutiliser une classe
parente de même nom si elle n'a pas exactement les mêmes arguments. 'est
bien beau, c'est intélligent quand je fais des interfaces ou des classes
publiques avec des petites spécialisations, mais certaines méthodes sont
utilitaires et n'ont aucune raison de se retrouver "forcées" ainsi. Ca
va m'empecher de faire de la réutilisation ça ...


Il y a deux workaround :
- passer en mode de compatibilité PHP4, on perd alors pas mal de trucs
PHP5 (les références par exemple)
- mettre des valeurs par défaut pour les paramètres supplémentaires,
mais ce n'est pas vraiment pertinent pour tout


Je trouve tellement stupide de forcer les prototypes quand il n'y a pas
d'interface en jeu que je me dis que j'ai du louper un point dans la
justification.
Quelqu'un a des réactions ?

--
Eric

1 réponse

Avatar
Bruno Desthuilliers
Eric Daspet wrote:
Voilà, l'équipe de dev PHP a fait un truc qui va faire parler un bon
moment. Désormais le code suivant génère une erreur (sisi, dans le futur
PHP5) :

class maClasse {
function maFonction( $monArgument ) {
// ... instructions
}
}

class maDerivee {
function maFonction( $monArgument, $deuxiemeArgument ) {
// ... instructions
}
}



Dans la mesure où il n'y a aucune relation entre ces deux classes - si
ce n'est le nom d'une méthode - je doute que ce code soit supposé
générer une erreur. Ou alors les petits gars de chez Zend ont abusé de
la moquette...

Mais peut-être manque-t'il un 'extends maClasse' dans la déclaration de
maDerivee ?-)

(snip)

Il n'est donc simplement plus possible de dériver une classe en lui
donnant des spécificités fortes. On ne pourra plus réutiliser une classe
parente de même nom si elle n'a pas exactement les mêmes arguments. 'est
bien beau, c'est intélligent quand je fais des interfaces ou des classes
publiques avec des petites spécialisations, mais certaines méthodes sont
utilitaires et n'ont aucune raison de se retrouver "forcées" ainsi.


Le principe de substitution, éventuellement ?

Ca
va m'empecher de faire de la réutilisation ça ...


Bon, de toutes façons tu ne peux plus substituer une instance de
maDerivee à une instance de maBase. Donc tu n'a pas besoin que maDerivee
soit une sous-classe de maBase. Donc tu peux faire de la réutilisation
par aggrégation / délégation (ce qui est conceptuellement préférable
dans ce cas de figure - à défaut d'être plus performant...) :

class maDerivee
{
var $_base;

function maDerivee() {
$this->_base = new maBase;
}

function maFonction($arg1, $arg2)
{
// code spécifique
}

function autreFonctionDeMaBase($arg)
{
$this->_base->autreFonctionDeMaBase($arg);
}
}

C'est plus propre - du point de vue conceptuel. C'est sûr que pour la
productivité ou les performances, c'est autre chose.

Je trouve tellement stupide de forcer les prototypes quand il n'y a pas
d'interface en jeu que je me dis que j'ai du louper un point dans la
justification.


Une volontée de rassurer les accros du typage statique ?-)

Plus sérieusement, je peux comprendre la logique en oeuvre, mais je ne
suis effectivement pas convaincu de sa pertinence, et surtout de sa
cohérence eu égard aux spécificités de PHP. Mais bon, il faudrait que je
me penche d'avantage sur les nouveautées de PHP5 pour me faire une idée...

Mes deux centimes...
Bruno