Modification de la signature d'une méthode d'interface

Le problème exposé dans ce sujet a été résolu.

Yop les gens,

dans la doc de PHP on peut lire

La classe implémentant l'interface doit utiliser exactement les mêmes signatures de méthodes que celles définies dans l'interface. Dans le cas contraire, une erreur fatale sera émise.

ce qui semble plutôt logique.

Pourtant il semble que si la signature est modifiée par l'ajout d'un paramètre optionnel alors tout baigne. Pour preuve ces codes

1
2
3
4
5
6
<?php

interface PackageInterface
{
    public function getUrl($path);
}
1
2
3
4
5
6
7
8
9
<?php

class ImageUrlGenerator implements PackageInterface
{
    public function getUrl($uri, array $options = array())
    {
        // ...
    }
}

qui n'affichent aucune erreur ni dans mon IDE (PhpStorm 8.0.3), ni à l'exécution (PHP 5.6.4).

Ce cas est-il traité quelque part dans la doc' ? Puis-je me baser dessus pour la suite des développements ?

Merci d'avance !

+0 -0

Hello,

En regardant la doc', on a aussi :

De plus, les signatures de ces méthodes doivent correspondre, ce qui signifie que les types des paramètres et le nombre d'arguments requis doivent être les mêmes. Par exemple, si la classe enfant définit un argument optionnel, alors que la signature de la méthode abstraite ne le définit pas, il n'y aura aucun conflit dans la signature.

http://php.net/manual/fr/language.oop5.abstract.php

Apparemment, les arguments optionnels n'apparaissent pas dans la signature, donc le comportement est fiable. :)

Edit: je sais que la doc' que je lie parle des classes abstraites, m'enfin la signature c'est quelque chose de commun partout.

+3 -0

Je n'avais rien dit parce que je n'avais pas vraiment le temps chercher une source et répondre, mais c'est aussi le comportement d'autres langages orientés objet, ce qui permet désormais aux devs PHP de redéfinir des méthodes avec justement des paramètres supplémentaires.

+0 -0

Ça me fait tout de même vraiment bizarre de me dire qu'il suffit qu'un paramètre soit optionnel pour qu'il ne fasse plus partie de la signature.

MatTheCat

Complètement d'accord.
En plus, je viens de faire le test, on ne peut pas mettre de paramètre optionnel dans l'interface sans l'implémenter dans sa classe. Pourtant, d'après la doc', c'est bien censé avoir la même signature.

J'ai pas vraiment le temps de chercher, mais sauf erreur (je n'en suis plus vraiment sûr  :-° ), Java se comporte de manière similaire. Bon, il supporte la surcharge de méthodes, donc ceci explique probablement cela, mais du coup, ça pourrait être une piste : les langages permettant de gérer la surcharge de méthode permettent-ils ce genre de comportement que PHP propose désormais ?

+0 -0

En Java, la question n'a pas de sens, vu que les paramètres optionnels n'existent pas. C'est de toute façon des méthodes différentes avec des signatures différentes.

ARrêtez-moi si je dis une bêtise, mais en python et ruby ça n'a pas de sens non plus puisqu'il n'y a pas d'interfaces.

Du côté du C++, les paramètres optionnels font bien partie de la signature (les valeurs par défaut sont attribuées à la compilation).

En fait ce qui me paraît surprenant ici, c'est pas que ça ne fasse pas d'erreur, mais que ça ne soulève même pas de notice strict. Je me suis fait avoir en migrant de je ne sais plus quelle version, de 5.2 à 5.3 il me semble, ou pour un cas très similaire, la redéfinition d'une méthode dans une sou-classe en ajoutant un paramètre optionnel, j'ai eu soudainement droit à des notices strict. Du coup solution rapide mais crado, j'ai dû modifier la classe parente en ajoutant aussi un paramèbre bidon avec un nom genre $_.

+0 -0

En plus, je viens de faire le test, on ne peut pas mettre de paramètre optionnel dans l'interface sans l'implémenter dans sa classe.

C'est logique !

Les valeurs par défaut sont sensées être propres à l'implémentation. Si tu la mets dans l'interface, ça veut dire qu'il faudra qu'il y ait cet argument, c'est le principe de l'interface.

Je le pensais aussi au début, puis ensuite j'ai considéré les deux bouts de documentation suivants :

La classe implémentant l'interface doit utiliser exactement les mêmes signatures de méthodes que celles définies dans l'interface

et

les signatures de ces méthodes doivent correspondre, ce qui signifie que les types des paramètres et le nombre d'arguments requis doivent être les mêmes.

Donc les paramètres optionnels n'appartiennent pas à la signature (ce qui répondait à la question de l'OP). Mais. Si les paramètres optionnels n'appartiennent pas à la signature, d'après la doc je ne suis pas obligé de les implémenter dans ma méthode de classe.
Enfin, tout ça pour dire qu'il y a une faille de logique dans la doc. Cela dit, je doute que ce soit critique.

Edit : vous savez s'il y a moyen de mettre deux citations à la suite en Markdown, sans devoir rajouter un "et" entre les deux pour faire bonne mesure ?

+0 -0

Donc les paramètres optionnels n'appartiennent pas à la signature (ce qui répondait à la question de l'OP). Mais. Si les paramètres optionnels n'appartiennent pas à la signature, d'après la doc je ne suis pas obligé de les implémenter dans ma méthode de classe. Enfin, tout ça pour dire qu'il y a une faille de logique dans la doc. Cela dit, je doute que ce soit critique.

C'est une question de "remplaçabilité" de la signature.

ce quand tu mets dans ta classe un argument optionnel, tu dis "je peux utiliser la méthode avec ou sans argument" autrement dit, la nouvelle signature peut tout à fait "remplacer" la précédente. PHP n'est pas statiquement typé, si bien que tant que les méthodes cancanent comme des canard, on dit qu'elles sont des canards.

Quand tu la mets dans l'interface, tu dis "il y aura un argument par défaut", par définition d'une interface, c'est une obligation. Il n'y aura pas de "remplaçabilité", il faudra qu'il y ait un argument et qu'il soit optionnel. Pour "cancaner" comme la méthode de l'interface, il faut avoir un argument optionnel.

J'avais bien compris, ne t'inquiète pas. :)

Ce que je dis, c'est que d'un point de vue strictement logique, du fait de la définition étrange de la signature, on peut interpréter la doc comme autorisant la définition d'un paramètre optionnel dans l'interface sans l'implémenter dans sa classe. Ça m'a fait douter, j'ai testé, ça n'a pas marché, et j'en ai conclu que cette histoire était cheloue puisqu'il y a contradiction entre ce que laisse entendre la doc et la logique que tu as décrite (qui est bien celle implémentée, nous sommes d'accord).

Ce que je dis, c'est qu'il y a une erreur dans la rédaction de la doc, pas qu'il y a un bug dans PHP.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte