Использую агрегирование в PHP, как правильно указать интерфейс?

Например, есть такая ситуация.

interface ITest
{
    public function test();
}

class Test implements ITest
{
    ...
}

interface ITest2 extends ITest
{
    public function test($a = '');
}

class Test2 extends Test implements ITest2
{
    ...
}

class WorkWithTest
{
    protected ITest $var;

    public function __construct($test)
    {
        $this->var = $test;
    }
}

class WorkWithTest2 extends WorkWithTest
{
    protected ITest2 $var; //PHP Fatal error:  Type of WorkWithTest2::$var must be ITest

    public function __construct($test2)
    {
        $this->var = $test2;
    }
}

Как в класс WorkWithTest2 сделать так, чтобы он работал только с инстансами, что реализуют интерфейс ITest2?


Ответы (1 шт):

Автор решения: Borislav

Сделайте свойство приватным:

interface ITest
{
    public function test();
}

class Test implements ITest
{
    ...
}

interface ITest2 extends ITest
{
    public function test($a = '');
}

class Test2 extends Test implements ITest2
{
    ...
}

class WorkWithTest
{
    private ITest $var;

    public function __construct($test)
    {
        $this->var = $test;
    }
}

class WorkWithTest2 extends WorkWithTest
{
    private ITest2 $var; //PHP Fatal error:  Type of WorkWithTest2::$var must be ITest

    public function __construct($test2)
    {
        $this->var = $test2;
    }
}

Ваша проблема в том, что вы используете наследование, однако, в этом нет смысла, оно вам только мешает.

Если вы не используете свойство правильно в контексте наследования, то не нужно вовсе его наследовать.

→ Ссылка