gpt4 book ai didi

php - $this 在继承方法上的行为

转载 作者:行者123 更新时间:2023-12-02 07:42:39 24 4
gpt4 key购买 nike

我一直认为我了解 OOP 的工作原理(我已经使用它多年),但有时我意识到有些概念对我来说仍然不是很清楚。

我刚刚遇到 this question关于 PHP 中的方法可见性。 accepted answer说明私有(private)方法不能被 PHP 中的子类覆盖。好的,这是有道理的。然而,这个例子让我思考了 PHP 中的内部继承机制,以及 $this 在继承方法上的行为方式。

考虑这段代码( example from the PHP Manual ,也包含在上面提到的问题中):

class Bar 
{
public function test() {
$this->testPrivate();
$this->testPublic();
}

public function testPublic() {
echo "Bar::testPublic\n";
}

private function testPrivate() {
echo "Bar::testPrivate\n";
}
}

class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}

private function testPrivate() {
echo "Foo::testPrivate\n";
}
}

$myFoo = new foo();
$myFoo->test();

/*
Output:

Bar::testPrivate
Foo::testPublic
*/

现在考虑这个 excerpt from the PHP Manual :

The pseudo-variable $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but possibly another object, if the method is called statically from the context of a secondary object).

解释说明“$this 是对调用对象的引用”,即$myFoo。所以我预计 $myFoo->test() 将始终调用 Foo::testPrivate,而永远不会调用 Bar::testPrivate(除非 $myFooBar 的实例)。我用 get_class 测试了 $this,它总是返回 Foo,即使是从 Bar::testPrivate栏::测试。但是,当 Bar::test 调用 $this->testPrivate() 时,$this 的行为类似于 Bar 的实例>.

这真的很令人困惑,我正在努力理解为什么它是这样工作的!

我认为继承方法(publicprotected)以某种方式从基类复制到子类。私有(private)方法根​​本不会被复制。但是这个例子表明它不是这样工作的。看起来 Foo 的实例保留了 Bar 的内部实例,并在必要时将方法调用委托(delegate)给它。

我想在这里学习一些东西,而且只有当事情对我有意义时我才会学习。这个没有。写完这一切,我想我可以用两个问题来总结:

  1. 有人可以简要解释继承在 PHP 中内部的工作原理吗?或者至少给我指点有关的文章或文档?

  2. 此处讨论的行为或 $this 是否也存在于其他 OO 语言中,或者它是否特定于 PHP?

最佳答案

PHP 中的继承与大多数面向对象语言中的继承方式相同。

当您拥有“虚拟”方法时,该方法不会直接绑定(bind)到调用者。相反,每个类都包含一个小查找表,上面写着“这个方法名称绑定(bind)到那个实现”。所以,当您说 $this->testPublic() 时,实际发生的是 PHP:

  • 获取当前类的虚拟表
  • 在该表中查找 testPublic 的虚拟表条目
  • 调用查找指向的方法

由于 Foo 覆盖了 testPublic,它的虚拟表包含一个用于 testPublic 的条目,指向 Foo::testPublic .

现在,有了私有(private)方法,行为就不同了。因为,正如您正确阅读的那样,私有(private)方法不能被覆盖,所以调用私有(private)方法永远不会导致虚拟表查找。也就是说,私有(private)方法不能是虚拟的,必须始终在使用它们的类中定义。

因此,效果是名称在声明时绑定(bind):所有 Foo 方法在调用 Foo::testPrivate 时调用 $this ->testPrivate,所有 Bar 方法都将调用 Bar::testPrivate

综上所述,说“继承的方法复制给 child ”是不正确的。实际发生的情况是,子类从其方法名称查找表开始填充其父类的条目,然后添加自己的函数并替换任何被覆盖的条目。当您调用 $this->something 时,将查询此查找表当前对象的类。因此,如果 $thisFoo 的一个实例,并且 Foo 覆盖 testPublic,您将得到 Foo: :testPublic。如果 $thisBar 的实例,您将得到 Bar::testPublic

关于php - $this 在继承方法上的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9436352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com