Объявление Specific :: method (): должно быть совместимо с General :: method (). PHP не прав насчет LSP?

Я полагаю, что «… должно быть совместимо с …» для обеспечения соблюдения принципа замены Лискова. Но я не уверен, что это то, что говорит LSP?

У меня есть такой код:

class General
{
public static function create(): General
{
return new static;
}

public function doSomething()
{
echo get_class($this) . ' speaking!' . PHP_EOL;
}
}


class Specific extends General
{
public static function create(): Specific
{
return parent::create();
}
}


function doSomething(General $object)
{
$object->doSomething();
}

doSomething(General::create());
doSomething(Specific::create());

Который производит:

Фатальная ошибка PHP: Объявление Specific :: create (): Specific должно быть совместимо с General :: create (): General в …

LSP часто упоминается как:

Функции, которые используют указатели или ссылки на базовые классы, должны быть в состоянии
использовать объекты производных классов, не зная этого.

И это не нарушено здесь, насколько я понимаю. Так что здесь не так? Это какое-то особое ограничение, которое не имеет ничего общего с LSP? Это ошибка в PHP? Я делаю что-то не так, не зная?

ОБНОВЛЕНИЕ: я нашел эту тему (Тип параметра ковариация в специализациях). Я понимаю и полностью согласен, что пример там нарушает LSP. Но у меня ситуация другая (на самом деле наоборот).

1

Решение

http://php.net/manual/en/functions.returning-values.php

При переопределении родительского метода дочерний метод должен соответствовать любому объявлению возвращаемого типа в родительском методе. Если родитель не определяет тип возвращаемого значения, тогда дочерний метод может сделать это.

Ваш Specific::create функция должна указывать General тип возврата.

В противном случае код написан для Specific::create потенциально может сломаться при запуске General::createкак бы получил другой класс.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]