Я видел следующий фрагмент кода PHP, объявляющий некоторые интерфейсы, абстрактные классы и конкретные классы:
public interface MyInterface
{
public function method1() : MyAbstractClass;
}
abstract class MyAbstractClass implements MyInterface
{
protected $myVar = 1;
}
public class MyClass1 extends MyAbstractClass
{
function method1(): MyAbstractClass
{
return new MyClass1();
}
}
public class MyClass2 extends MyAbstractClass
{
function method1(): MyAbstractClass
{
return new MyClass2();
}
}
Некоторые комментаторы утверждали, что существует круговая зависимость, и, следовательно, method1
должен вернуться MyInterface
вместо MyAbstractClass
,
будет ли это так?
Я бы опубликовал это как комментарий, но это долго читать.
Я полагаю, что ни один не является «неправильным» per se. Но то, что кажется «правильным», будет примерно таким:
public interface MyInterface
{
public function method1() : self;
}
abstract class MyAbstractClass implements MyInterface
{
protected $myVar = 1;
}
public class MyClass1 extends MyAbstractClass
{
function method1(): self // yes, you can return self
{
return $this;
}
}
public class MyClass2 extends MyAbstractClass
{
function method1(): self
{
return $this;
}
}
Причина возврата self в интерфейсе заключается в том, что класс, который реализует этот интерфейс и всегда возвращает $this
всегда вернется … ну … сама.
Если бы вы должны были вернуться MyAbstractClass
в интерфейсе это сделало бы сам интерфейс избыточным, поскольку он может быть реализован только этим абстрактным классом, который полностью отрицает цель даже наличия интерфейса.
method1
должен вернуться self
или класс, в котором он в настоящее время проживает. Конечно, вы можете вернуть родительский класс, так как при наследовании тип возвращаемого значения правильный.
Вы также можете вернуть интерфейс, что тоже прекрасно. На самом деле, в некоторой степени это кажется «лучше» или «более правильным», но в конечном итоге все сводится к return self
,
Мои 2 цента. Последнее утверждение относительно method1
открыт для интерпретации, но в конечном счете, первый, касающийся интерфейса, определенно не должен быть. Интерфейс никогда не должен иметь возвращаемый тип класса, который его реализует.
Это отстой, что PHP еще не static
как допустимый тип возвращаемого значения. Это решило бы проблему по определению.
Смотрите этот вопрос также
Интерфейсы PHP 7, подсказки возвращаемого типа и self
Принятый ответ делает справедливое замечание.
Других решений пока нет …