首页 > 解决方案 > PHP:理解 $this - 调用基类方法而不是子方法

问题描述

阅读 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 更改为 public 时,情况会发生变化。

标签: phpinheritancethisvisibilitylate-binding

解决方案


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

这就是设计。当你考虑它时,它是有道理的。通俗地说,继承就是关于通用的属性和方法。所以最合乎逻辑的事情是从链的顶部开始 - 具有最常用方法/属性的级别(大多数作为最高级,而不是作为量词)。这是简化的逻辑:

  • 父类有方法吗?
  • 如果没有,请检查子类。如果是,请检查能见度。
  • 如果 child 可以覆盖该方法,请检查它是否具有覆盖的方法。
  • 如果没有,请运行父级。如果是,运行孩子。
  • 如果子级无法覆盖,请运行父级。

最后一点是您示例的关键。父类不期望子类具有相同方法的实现。当您将父类中的方法声明为私有时,您是在说子类没有处理此问题的业务。所以在子类中创建同名方法是没有意义的。如果孩子需要使用它,则需要根据用例将该方法公开或保护。

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


推荐阅读