Классовая круговая зависимость

Я видел следующий фрагмент кода 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,

будет ли это так?

2

Решение

Я бы опубликовал это как комментарий, но это долго читать.

Я полагаю, что ни один не является «неправильным» 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

Принятый ответ делает справедливое замечание.

4

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

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