Les fonctions statiques abstraites ne sont pas absurdes ! En fait, elles permettent des conceptions qui sont, à mon sens, plus simples et plus propres que celles auxquelles je devrais recourir dans un langage qui ne les possède pas, comme Java ou C#.
Prenons un exemple. Supposons que j'écrive une application d'entreprise banale qui doit synchroniser certains objets commerciaux entre deux API. Ces API ont des modèles d'objets qui peuvent être mappés les uns aux autres, mais utilisent des noms différents et des formats de sérialisation différents.
En PHP, grâce aux méthodes statiques abstraites, je peux définir une classe de base abstraite pour ces types d'objets métier qui ressemble à ceci...
abstract class ApiObject {
/** The REST resource URL for this object type in the Foo API. */
abstract static function fooApiResourceUrl();
/** The REST resource URL for this object type in the Bar API. */
abstract static function barApiResourceUrl();
/** Given an XML response from the Foo API representing an object of this
type, construct an instance. */
abstract static function fromFooXml($xml);
/** Given a JSON response from the Bar API representing an object of this
type, construct an instance. */
abstract static function fromBarJson($json);
/** Serialize this object in the XML format that the Foo API understands */
abstract function toFooXml();
/** Serialize this object as JSON that the Bar API understands */
abstract function toBarJson();
}
... et ensuite chaque sous-classe concrète que je crée sera garanti pour fournir toutes les informations nécessaires pour le récupérer à partir de l'une ou l'autre des deux API et le désérialiser, ou pour le sérialiser et l'envoyer à l'une ou l'autre API. Ensuite, plus tard, je pourrai écrire un code comme celui-ci :
// Ensure that all instances of these types that exist in the Foo API also
// exist in the Bar API:
$classesToSync = ['Widget', 'Frobnicator', 'Lead', 'Invoice'];
foreach ($classesToSync as $apiObjectClass) {
$fooObjXmls = httpGetRequest($apiObjectClass::fooApiResourceUrl());
foreach ($fooObjXmls as $fooObjXml) {
$fooObj = $apiObjectClass::fromFooXml($fooObjXml);
$json = $fooObj->toBarJson();
httpPutRequest($apiObjectClass::barApiResourceUrl(), $json);
}
}
Est-ce que je dois strictement besoin de méthodes statiques abstraites pour écrire le programme ci-dessus ? Non, il y a d'autres modèles que j'aurais pu utiliser, comme avoir chaque classe de modèle associée à une classe de fabrique correspondante qui est responsable de son instanciation à partir de ses représentations JSON ou XML. Mais une telle conception est plus compliquée que celle que j'ai montrée ci-dessus.
La réponse à la question de savoir pourquoi ils sont autorisés, alors, est simplement qu'ils sont utile car ils permettent de réaliser des modèles simples et agréables qui ne seraient pas possibles sans eux. Bien sûr, il y a aussi des arguments contre L'une d'entre elles a été donnée dans la question - qu'il est laid d'exposer des méthodes statiques abstraites sur une classe étant donné que les méthodes statiques sur une classe abstraite sont appelables. Je ne trouve pas ces considérations particulièrement convaincantes, mais même si vous les trouvez, il y a toujours un compromis entre elles et l'utilité que les méthodes statiques abstraites fournissent, et les mainteneurs de PHP ont probablement pesé le pour et le contre en laissant les méthodes statiques abstraites exister.