PHP:理解$this - 调用基类方法而不是子方法

PHP: understanding $this - calling base class method instead of child method

提问人:Jack Scandall 提问时间:3/20/2020 更新时间:3/20/2020 访问量:553

问:

在阅读 PHP.net 文档时,我偶然发现了一个问题,它扭曲了我理解$this的方式:

class C {
    public function speak_child() {
        //echo get_class($this);//D
        echo $this->f();//calls method of C class... why?!
    }

    private function f() {
        echo "C";
    }
}

class D extends C {
    public function speak_parent() {
        echo $this->f();
    }
    public function f() {
        echo "D";
    }
}

$d= new D();
$d->speak_parent();
$d->speak_child();

由于$this是 D 类实例的表示形式,因此我期望输出:

DD

但是,实际输出是:

DC

为什么 $this->f() 宁愿访问基类方法,而不是子类方法? 当我们将 C->f 更改为公开时,情况会发生变化。

PHP 继承 可见 性后期绑定

评论


答:

1赞 Van Tho 3/20/2020 #1

因为 C 类的函数是私有的,所以不能被子类覆盖,子类不会看到它。因此,当您在子类中声明一个函数时,它是一个新函数,而不是从父类扩展而来的。ff

如果将函数声明为在父类中,也可以扩展函数。fprotected

在此处编码为官方文档

声明为私有的成员只能由定义该成员的类访问。

评论

0赞 Jack Scandall 3/20/2020
这是否意味着,$this同时依赖于:1)对象的实例(新D())2)调用$this的范围?
0赞 Van Tho 3/20/2020
是的,$this是依赖的,只有函数,vars 是扩展的
1赞 El_Vanja 3/20/2020 #2

为什么 $this->f() 宁愿访问基类方法,而不是子类方法?

这就是设计。仔细想想,这是有道理的。通俗地说,继承就是关于常见的属性和方法。因此,最合乎逻辑的事情是从链的顶部开始 - 具有最常见方法/属性的级别(大多数是最高级的,而不是量词)。下面是简化的逻辑:

  • 父类有方法吗?
  • 如果没有,请检查子类。如果是,请检查可见性。
  • 如果子项可以重写该方法,请检查它是否具有重写的方法。
  • 如果没有,请运行 parent。如果是,请运行子项。
  • 如果子项无法覆盖,请运行父项。

最后一点是你的例子的关键。父类不希望子类具有相同方法的实现。当你在父类中将一个方法声明为私有方法时,你是说子类没有处理这个问题的业务。因此,在子类中创建同名方法是没有意义的。如果子级需要使用它,则需要根据用例将该方法设为公共或受保护。

$this始终表示所构造的类的实例。但是,您必须记住,子类既表示自身的实例,也表示父类的实例。方法和属性的使用将取决于上述逻辑。