php - 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 时,情况会发生变化。
解决方案
为什么 $this->f() 宁愿访问基类方法,而不是子类方法?
这就是设计。当你考虑它时,它是有道理的。通俗地说,继承就是关于通用的属性和方法。所以最合乎逻辑的事情是从链的顶部开始 - 具有最常用方法/属性的级别(大多数作为最高级,而不是作为量词)。这是简化的逻辑:
- 父类有方法吗?
- 如果没有,请检查子类。如果是,请检查能见度。
- 如果 child 可以覆盖该方法,请检查它是否具有覆盖的方法。
- 如果没有,请运行父级。如果是,运行孩子。
- 如果子级无法覆盖,请运行父级。
最后一点是您示例的关键。父类不期望子类具有相同方法的实现。当您将父类中的方法声明为私有时,您是在说子类没有处理此问题的业务。所以在子类中创建同名方法是没有意义的。如果孩子需要使用它,则需要根据用例将该方法公开或保护。
$this
总是代表你构造的类的实例。但是,您必须记住,子类既代表自身的实例,也代表父类的实例。方法和属性的使用将取决于上述逻辑。
推荐阅读
- gradle - 如何让 gradle 处理多个代理?
- linux - 无法在我的 Linux Mint 上连接到互联网,即使我的路由器有互联网
- html - 使用 ES6 导出/导入时出现 MIME 类型错误
- java - jpql和hibernate的年龄差
- php - 在 Linux 服务器上无法识别 DOCTYPE(仅在 IE 中)
- node.js - Gitlab webhook 系统
- elasticsearch - 在一个索引中通过 1-N 个相关数据的多个字段进行弹性搜索
- java - TimeFormat 始终来自特定时区
- python - Leetcode:提交的函数产生意外的输出
- python - 如何在python中使用空行结束程序?