changement de prototype dans une classe derive e PHP5
1 réponse
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 ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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
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...
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...