PHP 7.4 выдаст новое сообщение об ошибке устаревания , если псевдотип parent
используется в местах, которые не имеют родительского типа. Интерфейс является одним из примеров этого.
Когда я выполняю ваш код, я получаю 2 ошибки в PHP 7.4 :
Не рекомендуется: нельзя использовать «родительский», если в текущей области класса нет родительского элемента в / in / tOSug в строке 8
Неустранимая ошибка: не удалось проверить совместимость между B :: instanceOfParent (объект I1 $) и I2 :: instanceOfParent (родительский объект $), поскольку родительский класс недоступен в / in / tOSug в строке 22 * 1013 *
Это указывает, где проблема. Вы не можете использовать parent
в интерфейсе.
Вы можете исправить это, заменив parent
фактическим именем интерфейса:
// Duplication for completion...
interface I1 {}
interface I2 extends I1 {
public function instanceOfSelf(self $object);
public function instanceOfParent(I1 $object);
}
class A implements I1 {}
class B implements I2 {
private function printBool(bool $b) {
echo ($b ? 'true' : 'false') . "\n";
}
public function instanceOfSelf(I2 $object) {
$this->printBool($object instanceof I2);
}
public function instanceOfParent(I1 $object) {
$this->printBool($object instanceof I1);
}
}
$a = new A;
$b = new B;
$b->instanceOfSelf($b); // true
$b->instanceOfParent($a); // true
$b->instanceOfParent($b); // true
Достаточно интересно, что подсказка типа с помощью parent
не документирована в Руководстве по PHP под Объявления типов
Объяснение, почему код не ведет себя так, как вы ожидаете.
Ключевое слово parent
всегда относится к родительскому классу или, другими словами, к классу, который вы расширили. В вашем примере класс B
не имеет родителя. Он реализует только интерфейс.
class B {
public function amIanOrphan() {
var_dump(parent::class);
}
}
$b = new B;
$b->amIanOrphan();
Этот код выдаст ошибку:
Неустранимая ошибка: необученная ошибка: невозможно использовать «родительский элемент», если в области действия текущего класса нет родительского элемента
Интерфейсы сами по себе не являются классами. Интерфейс только сообщает вам, какие методы у класса.
Этот код точно такой же, как указано выше:
interface I1 {
public function amIanOrphan();
}
interface I2 extends I1 {
}
class B implements I2 {
public function amIanOrphan() {
var_dump(parent::class);
}
}
Интерфейс расширяется от другого, но сам класс все еще не имеет родителя. Приведенный выше код все равно выдаст ошибку, потому что B не имеет родителя, и та же логика применяется к подсказке типа.