call_user_func与子方法中的父方法

时间:2015-07-09 08:06:47

标签: php inheritance

我有以下代码:

class A {
    protected $v = 'a';

    public function f() {
        echo 'f in A: ('.get_class($this).', '.$this->v.')<br/>';
    }
}

class B extends A {
    protected $v = 'b';
    public function f() {
        echo 'f in B: ('.get_class($this).', '.$this->v.')<br/>';
        call_user_func(array($this, 'parent::f'));
    }
}

class C extends B {
    protected $v = 'c';
}

$a = new A();
$b = new B();
$c = new C();

$a->f();
$b->f();
$c->f();

我的预期输出是:

f in A: (A, a)

f in B: (B, b)
f in A: (B, b)

f in B: (C, c)
f in A: (C, c)

但我得到的是最后的无限循环。经过一些研究后,有人在call_user_function(array($this, 'parent::f'))中使用B::fC调用了// Option 1, explicit specification of the parent class call_user_func(array($this, 'A::f')) ; // Option 2, use of __CLASS__ instead of $this call_user_func(array(__CLASS__, 'parent::f')) ; // Option 3, combination of both options 1 and 2 call_user_func(array(__CLASS__, 'A::f')) ;

从那里,我找到了3个可行的选项,但我不知道哪个是“好”的方式。 以下三种方法中的哪一种是“正确”方式?

toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
toolbar.setTitle(itemType);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);

1 个答案:

答案 0 :(得分:3)

您已正确识别此代码:

call_user_func (array($this, 'parent::f'));

C的上下文中运行时,将继续致电B::f,因为$this始终是C的实例,而C的父级始终是B

要修复它,您可以轻松完成:

call_user_func('parent::f');

它没有对调用类的引用,因此它将正确解析父类。

在您提供的工作替代方案中,以下是更好的方法:

call_user_func (array(__CLASS__, 'parent::f'));

这是因为__CLASS__总是引用它出现的类声明,因此始终为B