Должен ли конкретный класс следовать типовой подсказке его интерфейса? - PullRequest
0 голосов
/ 22 декабря 2018

В этом примере кода интерфейсу не важно, проверяет ли метод реализации foo() параметр типа array, даже если он явно указывает на подсказку типа array только.

<?php

declare(strict_types = 1);

interface MyInterface
{
    public function foo(array $foo);
}


class Bar implements MyInterface
{
    public function foo($foo)
    {
        return $foo;
    }
}


echo (new Bar)->foo('test'); // runs just fine as string

Я бы ожидал по крайней мере фатальной несовместимой ошибки интерфейса;но их нет.

Мои вопросы:

  1. Это ожидаемое поведение?
  2. Разве у интерфейса вообще нет подсказок типа, потому что он все равно не соблюдается?

1 Ответ

0 голосов
/ 24 декабря 2018

Краткий ответ:

Это ожидаемое поведение начиная с версии 7.2, и подсказки типов интерфейсов применяются в определенной степени;но реализующие классы могут опустить объявление типа интерфейса (но не может объявить тип параметра, отличный от того, который объявлен в интерфейсе).

Длинный ответ:

Этобыло внесено изменение в PHP 7.2.

Если вы попробуете это в PHP, где PHP_VERSION_ID >= 7 && PHP_VERSION_ID < 7.2 вы получите:

Неустранимая ошибка: объявление Bar :: foo ($ foo) должнобыть совместимым с MyInterface :: foo (массив $ foo)

Но на PHP_VERSION_ID >= 7.2 это "работает".Объяснение изменений задокументировано здесь и гласит:

Расширение типа параметра

Типы параметров из переопределенных методов и реализаций интерфейса теперь могут быть опущены.Это все еще соответствует LSP, так как типы параметров противоречивы.

interface A {
    public function Test(array $input); }

class B implements A {
    public function Test($input){} // type omitted for $input }

Вы можете опустить тип параметра, но вы не можете объявить несовместимый тип.

Например, если в вашем примере вы пытались:

public function foo(string $foo)
{
    return $foo;
}

Это не получится.

Несколько ссылок для дальнейшего чтения относительно этого изменения:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...