0

因此,我一直在阅读有关Late Static Bindings的官方 PHP 文档,并遇到了一个令人困惑的示例:

<?php
class A {
    private function foo() {
        echo "success!\n";
    }
    public function test() {
        $this->foo();
        static::foo();
    }
}

class B extends A {
   /* foo() will be copied to B, hence its scope will still be A and
    * the call be successful */
}

class C extends A {
    private function foo() {
        /* original method is replaced; the scope of the new one is C */
    }
}

$b = new B();
$b->test();
$c = new C();
$c->test();   //fails
?>

示例的输出:

success!
success!
success!


Fatal error:  Call to private method C::foo() from context 'A' in /tmp/test.php on line 9

有人可以解释为什么私有方法 foo() 被复制到 B 吗?据我所知,只有公共和受保护的属性会被复制到子类。我错过了什么?

4

1 回答 1

1

也许注释“foo() 将被复制到 B”有点令人困惑或解释不正确。foo() 仍然是 A 私有的,只能从 A 中的方法访问。

IE。在示例中,如果您尝试执行$b->foo()它仍然会按预期失败。

这是我向自己解释的示例,可能对其他人有帮助:

考虑 B 类。

$b->test()能够以 A 的公共成员身份访问 foo()。

$this->foo()内也成功$b->test()

$static::foo()成功是因为它从 A 中定义的 test() 调用 A 中定义的 foo() 版本。没有范围冲突。

考虑 B 类。

当 foo() 在类 C 中被覆盖时, $c->test()当然仍然可以作为公共成员访问,如果 A.

并且在$c->test()$this->foo() 内可以作为 A. 的私有成员访问 - 一切都很好。

但是 $static::foo()现在正在尝试从 A 访问,在类 C 中定义的 foo() 版本因此失败,因为它在 C 中是私有的。 - 根据错误消息。

于 2018-08-26T00:27:31.400 回答