Type Php allusion à ne pas s'entendre avec les interfaces et les classes abstraites?
Je pense que ça va être beaucoup plus facile de voir le problème dans un exemple de code que pour la rédaction de la question en premier lieu. Voici mon code php:
<?php
interface AnInterface
{
public function method();
}
class AClass implements AnInterface
{
public function method()
{
echo __METHOD__;
}
}
abstract class AnAbstractClass
{
abstract public function method( AnInterface $Object );
}
class ConcreteClass extends AnAbstractClass
{
public function method( AClass $Object )
{
$Object->method();
}
}
$Object1 = new ConcreteClass();
$Object2 = new AClass();
$Object1->method( $Object2 );
Le code ci-dessus les causes de l'erreur suivante:
Erreur fatale: Déclaration de ConcreteClass::methode() doit être compatible avec celle de AnAbstractClass::methode()
Le problème est que php ne semble pas être reconnaissant la signature de AnAbstractClass::méthode et ConcreteClass::méthode comme compatible. Suis-je en train de faire quelque chose de mal? Merci!
- S'il vous plaît, prenez l'habitude de poster le message d'erreur de votre code à générer. Poster du code sans affichage de la sortie (ou d'erreur) est inutile.
Vous devez vous connecter pour publier un commentaire.
PHP est correct, ils sont pas compatible. En autorisant uniquement les instances de
AClass
(ou ses enfants) pour être transmis àConcreteClass::method
, vous êtes de rompre le contrat quiAnAbstractClass
offre: l'un de ses sous-classes doivent accepterAnInterface
comme un argument de sonmethod()
.Si votre exemple, et j'ai eu une autre classe
BClass
la mise en œuvre deAnInterface
, nous aurions une situation où, selonAnAbstractClass
,method()
doit accepter les instances deBClass
, alors que, selonConcreteClass
, il ne devrait pas.Modifier votre signature pour
ConcreteClass::method
correspondre à celui de laAnAbstractClass::method
.Ne calcule pas. Nous avons eu la même discussion d'hier:
Peut les types de paramètre être spécialisé en PHP
Tous vos classes dérivées doivent mettre en œuvre la méthode des signatures de la même manière.
C'est quelque chose qui devrait idéalement être vérifié au moment de l'exécution. Mais en PHP, l'analyseur ne. (Pour compenser, PHP ne permet pas de vérifier privé/attribut protégé l'accès à l'analyse en temps, mais le laisser plutôt exploser au moment de l'exécution.)
Si vous souhaitez appliquer des mesures plus strictes type, je vous conseille:
assert($Object instanceof AClass);
Voici un exemple qui montre, pourquoi cela n'est pas permis:
Ce serait un code valide, mais il ne pourrait pas, si vous passez un
ConcreteClass
de moo, car sa méthodeConcreteClass::method
ne permet pasBClass
.C'est compliqué, mais c'est plus facile à comprendre, si vous pouvez voir un exemple.