@psfpro

Как правильно указать типа параметр при имплементации интерфейса в PHP?

Задался вопросом почему объект класса не совместим с типом object. Пример ниже:
interface ExtractorInterface
{
    /**
     * @param object $object
     * @return array
     */
    public function extract(object $object);
}

class MyObjectExtractor implements ExtractorInterface
{
    /**
     * @param MyObject $object
     * @return array
     */
    public function extract(MyObject $object)
    {
        return [
            'a' => $object->a,
        ];
    }
}

class MyObject
{
    public $a;
}

Есть вариант не указывать тип и делать проверку внутри метода. Ещё менее надежный метод не указывать тип вообще.
Как правильно использовать типизацию? Или может быть не использовать?
  • Вопрос задан
  • 174 просмотра
Решения вопроса 1
@psfpro Автор вопроса
В PHP 7.2 добавили возможность расширения типа параметра
https://wiki.php.net/rfc/parameter-no-type-variance
<?php
 
class ArrayClass {
  public function foo(array $foo) { /* ... */ }
}
 
 
// This RFC proposes allowing the type to be widened to be untyped aka any
// type can be passed as the parameter.
// Any type restrictions can be done via user code in the method body.
class EverythingClass extends ArrayClass {
  public function foo($foo) { /* ... */ }
}

Получается в моем примере не указывать тип и делать проверку внутри метода
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
alexey-m-ukolov
@alexey-m-ukolov Куратор тега PHP
Задался вопросом почему объект класса не совместим с типом object.
Наоборот - это object несовместим с MyObject.

Вообще, вы неправильно делаете - ваш интерфейс получается бессмысленным. Это MyObject должен имплементировать интерфейс Extractable и иметь метод extract - тогда никаких проблем и противоречий.

interface Extractable
{
    public function extract(): array;
}

class MyObject implements Extractable
{
    public $a;

    public function extract(): array
    {
        return [
            'a' => $this->a,
        ];
    }
}

class MyOtherObject implements Extractable
{
    public $a, $b, $c;

    public function extract(): array
    {
        return [
            'a-b' => $this->a . $this->b,
            'c' => $this->c->toArray(),
        ];
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Ведисофт Екатеринбург
от 25 000 ₽
YCLIENTS Москва
от 200 000 до 350 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽