Наследование типов классов DocBlock
Хотя этот вопрос касается DocBlocks в целом, мой пример использования касается PHP.
Рассмотрим следующий код PHP:
<?php
class ParentClass {
/**
* Says 'hi' to the world.
* @return ParentClass Returns itself for chaining.
*/
public function say_hi(){
echo 'hi';
return $this;
}
}
class ChildClass extends ParentClass {
/**
* Says 'bye' to the world.
* @return ChildClass Returns itself for chaining.
*/
public function say_bye(){
echo 'bye';
return $this;
}
}
$c = new ChildClass;
$c->say_hi()->say_b| <- type hinting won't suggest "say_bye" here
?>
Это просто тривиальный класс с некоторой цепочкой. Расширенный класс теряет подсказки типа, потому что докблок родительского класса использует конкретное имя класса, у которого нет методов / свойств дочернего класса.
Предполагая, что нам нужна возможность хинтинга типов (если нет, пожалуйста, оставьте этот вопрос - я не хочу здесь бесполезных аргументов), как мне это исправить?
Я придумал следующие возможности:
- Измените стандарт PHPDoc, чтобы разрешить специальное ключевое слово
- Добавьте лишний метод say_hi(), который вызывает родителя только для того, чтобы переопределить docblock
- Не указывайте тип возврата вообще, пусть IDE решит, что
return $this;
значит (это вообще работает?)
2 ответа
Вы можете решить это следующим образом:
class ParentClass {
/**
* Says 'hi' to the world.
* @return static
*/
public function say_hi(){
echo 'hi';
return $this;
}
}
Оператор "@return static" разрешает именно то, что вы хотите, PhpStorm прекрасно с ним работает.
То, что вы описываете, обычно называют "беглым интерфейсом", где все методы объекта выполняют свою работу и возвращают сам объект.
Я лично не видел ни одного окончательного руководства по PHPDoc о том, как именно это сделать. Таким образом, я не знаю, что какая-либо IDE предложила средства для его функции автозаполнения для обработки сценария использования.
Вероятный путь, по которому PHPDoc пойдет по этому пути, - это использование @return $ this в качестве соглашения для обозначения беглых методов, так как оно соответствует самому синтаксису кода и поэтому очень ясно. Я сомневаюсь, что любые IDE будут встраивать эту возможность до тех пор, пока сам стандарт не будет включать этот вариант использования.
В краткосрочной перспективе я думаю, что ваш лишний "ChildClass::say_hi(){parent::say_hit();}" может заставить ваше автозаполнение IDE работать. Опять же, может, потому что автозаполнение также распознает цепочку самого метода (например, $foo->bar()->baz()->roll()->tide();) может не существовать.