如何正确地将派生 class 的方法设置为父 class 的可调用方法?

How do I properly set method of derived class as callable for a parent class?

我正在编写一个带有一些 call_user_func() 的基本 class,然后使用我想从所述 call_user_func() 中调用的方法派生 class。看起来如下:

class Basic
{
    private $InputHandler = null;

    public function SetNewHandler(callable $NewHandler)
    {
        $this->InputHandler = $NewHandler;
    }

    public function ProcessInput()
    {
        call_user_func(array($this,$this->InputHandler));
    }
}

class Specific extends Basic
{
    public function Handler()
    {
        echo "Handler() is called\n";
    }
}

$spec = new Specific();
$spec->SetNewHandler('Specific\Handler');
$spec->ProcessInput();
unset($spec);

显然它不起作用,因为 Specific\Handler 未被识别为有效的可调用对象。 但实现这一结果的正确方法是什么?父 class 应该忽略派生 class and\or 处理程序方法的实现细节。

我用php7.4

如果您使用 call_user_func(array ($this, $this->InputHandler));方法名称应作为第二个数组元素。

class Basic
{
    private $InputHandler = null;

    public function SetNewHandler($NewHandler)
    {
        $this->InputHandler = $NewHandler;
    }

    public function ProcessInput()
    {
        call_user_func(array($this,$this->InputHandler));
    }
}

class Specific extends Basic
{
    public function Handler()
    {
        echo "Handler() is called\n";
    }
}

$spec = new Specific();
$spec->SetNewHandler('Handler');
$spec->ProcessInput();

而不是call_user_func(Array($this, $this->InputHandler));这在这里也有效吗:

$method = $this->InputHandler;
$this->$method();

或者这个:

$this->{$this->InputHandler}();

或者:可调用对象的传递与@Magnus Eriksson 在评论中所描述的类似。

class Basic
{
    private $InputHandler = null;

    public function SetNewHandler(callable $NewHandler)
    {
        $this->InputHandler = $NewHandler;
    }

    public function ProcessInput()
    {
        call_user_func($this->InputHandler);
                
    }
}

class Specific extends Basic
{
    public function Handler()
    {
        echo "Handler() is called\n";
    }
}

$spec = new Specific();
$spec->SetNewHandler([$spec,'Handler']);
$spec->ProcessInput();

我只想在基础中创建一个默认处理程序方法 class:

class Base
{
    public function ProcessInput()
    {
        $this->Handler();
    }

    public function Handler() 
    {
        // Some default code or just leave empty
        echo "Base Handler() is called\n";
    }
}

class Specific extends Base 
{
    public function Handler()
    {
        echo "Specific Handler() is called\n";
    }
}

$spec = new Specific;
$spec->ProcessInput();

这样您就不需要为每个实例手动绑定要使用的处理程序(这可能很麻烦)。如果您想要一个新的处理程序,请使用该处理程序创建一个新的 class。

这是一个demo