与 parent , static 以及 this 的区别
要想将彻底搞懂 self , 要与 parent , static 以及 this 区分开. 以下分别做对比.
parent
self 与 parent 的区分比较容易: parent 引用父类 / 基类被隐盖的方法(或变量), self 则引用自身方法(或变量). 例如构造函数中调用父类构造函数:
- class Base {
- public function __construct() {
- echo "Base contructor!", PHP_EOL;
- }
- }
- class Child {
- public function __construct() {
- parent::__construct();
- echo "Child contructor!", PHP_EOL;
- }
- }
- new Child;
- // 输出:
- // Base contructor!
- // Child contructor!
- static
static 常规用途是修饰函数或变量使其成为类函数和类变量, 也可以修饰函数内变量延长其生命周期至整个应用程序的生命周期. 但是其与 self 关联上是 PHP 5.3 以来引入的新用途: 静态延迟绑定.
有了 static 的静态延迟绑定功能, 可以在运行时动态确定归属的类. 例如:
- class Base {
- public function __construct() {
- echo "Base constructor!", PHP_EOL;
- }
- public static function getSelf() {
- return new self();
- }
- public static function getInstance() {
- return new static();
- }
- public function selfFoo() {
- return self::foo();
- }
- public function staticFoo() {
- return static::foo();
- }
- public function thisFoo() {
- return $this->foo();
- }
- public function foo() {
- echo "Base Foo!", PHP_EOL;
- }
- }
- class Child extends Base {
- public function __construct() {
- echo "Child constructor!", PHP_EOL;
- }
- public function foo() {
- echo "Child Foo!", PHP_EOL;
- }
- }
- $base = Child::getSelf();
- $child = Child::getInstance();
- $child->selfFoo();
- $child->staticFoo();
- $child->thisFoo();
程序输出结果如下:
- Base constructor!
- Child constructor!
- Base Foo!
- Child Foo!
- Child Foo!
在函数引用上, self 与 static 的区别是: 对于静态成员函数, self 指向代码当前类, static 指向调用类; 对于非静态成员函数, self 抑制多态, 指向当前类的成员函数, static 等同于 this , 动态指向调用类的函数.
parent , self , static 三个关键字联合在一起看挺有意思, 分别指向父类, 当前类, 子类, 有点 "过去, 现在, 未来" 的味道.
this
self 与 this 是被讨论最多, 也是最容易引起误用的组合. 两者的主要区别如下:
this 不能用在静态成员函数中, self 可以;
对静态成员函数 / 变量的访问, 建议 用 self , 不要用 $this:: 或 $this-> 的形式;
对非静态成员变量的访问, 不能用 self , 只能用 this ;
this 要在对象已经实例化的情况下使用, self 没有此限制;
在非静态成员函数内使用, self 抑制多态行为, 引用当前类的函数; 而 this 引用调用类的重写 (override) 函数(如果有的话).
self 的用途
看完与上述三个关键字的区别, self 的用途是不是呼之即出? 一句话总结, 那就是: self 总是指向 "当前类(及类实例)". 详细说则是:
替代类名, 引用当前类的静态成员变量和静态函数;
抑制多态行为, 引用当前类的函数而非子类中覆盖的实现;
槽点
这几个关键字中, 只有 this 要加 $ 符号且必须加, 强迫症表示很难受;
静态成员函数中不能通过 $this-> 调用非静态成员函数, 但是可以通过 self:: 调用, 且在调用函数中未使用 $this-> 的情况下还能顺畅运行. 此行为貌似在不同 PHP 版本中表现不同, 在当前的 7.3 中 ok;
在静态函数和非静态函数中输出 self , 猜猜结果是什么? 都是 string(4) "self" , 迷之输出;
return $this instanceof static::class;
会有语法错误, 但是以下两种写法就正常:
- $class = static::class;
- return $this instanceof $class;
- // 或者这样:
- return $this instanceof static;
来源: https://www.cnblogs.com/a609251438/p/11938922.html