121 votes

Pourquoi PHP 5.2+ interdit-il les méthodes abstraites des classes statiques ?

Après avoir activé les avertissements stricts en PHP 5.2, j'ai vu une charge d'avertissements de normes strictes d'un projet qui a été écrit à l'origine sans avertissements stricts :

Des normes strictes : Fonction statique Programme::getSelectSQL() ne doit pas être abstrait dans Programme.class.inc

La fonction en question appartient à une classe mère abstraite, Program, et est déclarée abstract static parce qu'elle doit être implémentée dans ses classes filles, comme TVProgram.

J'ai trouvé des références à ce changement aquí :

Suppression des fonctions abstraites des classes statiques. A cause d'un oubli, PHP 5.0.x et 5.1.x autorisait les fonctions statiques abstraites dans les classes. Depuis PHP 5.2.x, seules les interfaces peuvent les avoir.

Ma question est la suivante : quelqu'un peut-il expliquer de manière claire pourquoi il ne devrait pas y avoir de fonction statique abstraite en PHP ?

76voto

Jonathan Fingland Points 26224

Les méthodes statiques appartiennent à la classe qui les a déclarées. En étendant la classe, vous pouvez créer une méthode statique du même nom, mais vous n'implémentez pas en fait une méthode statique abstraite.

Il en va de même pour l'extension de toute classe avec des méthodes statiques. Si vous étendez cette classe et créez une méthode statique de la même signature, vous ne remplacez pas la méthode statique de la superclasse.

EDITAR (16 septembre 2009)
Mise à jour sur ce sujet. Avec PHP 5.3, je constate que l'abstraction statique est de retour, pour le meilleur ou pour le pire (cf. http://php.net/lsb pour plus d'informations)

CORRECTION (par philfreo)
abstract static n'est toujours pas autorisé en PHP 5.3, LSB est lié mais différent.

70voto

Wouter Van Vliet Points 461

Il existe une solution très simple pour résoudre ce problème, qui est en fait logique du point de vue de la conception. Comme l'a écrit Jonathan :

Il en va de même pour l'extension de toute classe avec des méthodes statiques. Si vous étendez cette classe et créez une méthode statique de la même signature, vous ne remplacez pas la méthode statique de la superclasse.

Donc, comme solution de contournement, vous pouvez faire ceci :

<?php
abstract class MyFoo implements iMyFoo {

    public static final function factory($type, $someData) {
        // don't forget checking and do whatever else you would
        // like to do inside a factory method
        $class = get_called_class()."_".$type;
        $inst = $class::getInstance($someData);
        return $inst;
    }
}

interface iMyFoo {
    static function factory($type, $someData);
    static function getInstance();
    function getSomeData();
}
?>

Et maintenant vous imposez que toute classe sous-classant MyFoo implémente une méthode statique getInstance, et une méthode publique getSomeData. Et si vous ne sous-classez pas MyFoo, vous pouvez toujours implémenter iMyFoo pour créer une classe avec une fonctionnalité similaire.

12voto

Petah Points 18432

Je sais que c'est vieux mais....

Pourquoi ne pas simplement lancer une exception dans la méthode statique de la classe parente, de cette façon, si vous ne la surchargez pas, l'exception est provoquée.

4voto

merkuro Points 4077

Je dirais qu'une classe/interface abstraite peut être considérée comme un contrat entre programmeurs. Il s'agit plus de savoir comment les choses doivent se présenter et se comporter que d'implémenter des fonctionnalités réelles. Comme on le voit dans php5.0 et 5.1.x, ce n'est pas une loi naturelle qui empêche les développeurs de php de le faire, mais l'envie de suivre d'autres modèles de conception OO dans d'autres langages. Fondamentalement, ces idées tentent d'empêcher un comportement inattendu, si l'on est déjà familier avec d'autres langages.

2voto

user2964021 Points 21

Je ne vois pas de raison d'interdire les fonctions abstraites statiques. Le meilleur argument pour dire qu'il n'y a aucune raison de les interdire est qu'elles sont autorisées en Java. Les questions sont les suivantes : - Sont-elles techniquement réalisables ? - Oui, puisqu'elles existaient en PHP 5.2 et qu'elles existent en Java. Donc on peut le faire. Devrions-nous le faire ? - Ont-ils un sens ? Oui. Il est logique d'implémenter une partie d'une classe et de laisser une autre partie de la classe à l'utilisateur. Cela a du sens pour les fonctions non statiques, pourquoi cela n'en aurait-il pas pour les fonctions statiques ? Les fonctions statiques sont utilisées pour les classes dont il ne peut y avoir plus d'une instance (singletons). Par exemple, un moteur de cryptage. Il n'a pas besoin d'exister en plusieurs instances et il y a des raisons de l'empêcher - par exemple, vous devez protéger une seule partie de la mémoire contre les intrus. Il est donc parfaitement logique de mettre en œuvre une partie du moteur et de laisser l'algorithme de cryptage à l'utilisateur. Ceci n'est qu'un exemple. Si vous avez l'habitude d'utiliser des fonctions statiques, vous en trouverez beaucoup d'autres.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X