PHP: «Декларация … должна быть совместима с тем …»

Я хотел бы создать интерфейс для объектов, которые являются CRUDable (могут быть сохранены и удалены). Вот мой абстрактный класс:

abstract class AbstractCrudableEntity extends AbstractEntity { abstract public function doSave(); abstract public function doDelete(); } 

Мой класс реализации нуждается в дополнительных параметрах для этих методов. Вот подпись реализующего класса:

 class Contact extends AbstractCrudableEntity { public function doSave(User $user, \UberClientManager $manager); public function doDelete(User $user, \UberClientManager $manager); } 

Я понимаю, что PHP требует, чтобы классы реализации имели те же параметры для методов, что и родительский класс (на этот вопрос задаются несколько вопросов: это , например). Так что это не проблема.

Однако недавно я встретил некоторый код в Symfony, посвященный токенам аутентификации. Класс UsernamePasswordToken расширяет AbstractToken и имеет другой набор параметров в методе __construct() : AbstractToken::__construct() сравнению с UsernamePasswordToken::__construct() .

Мой вопрос в том, как Symfony может это сделать? В чем разница между этим и моим кодом?

Главные конструкторы – это особый случай :

В отличие от других методов, PHP не будет генерировать сообщение об ошибке уровня E_STRICT когда __construct() переопределяется с разными параметрами, чем у родительского метода __construct() .

Вы не можете сделать это с помощью других методов.

Ваши дочерние методы должны иметь такое же количество параметров, что и абстрактные методы в абстрактном родительском классе.

Конструктор в вашем примере не является абстрактным – ребенок просто переопределяет его.