PHP static 延迟静态绑定

首先看这种写法

 1 <?php
 2 abstract class A
 3 {
 4     public static function create(): A
 5     {
 6         return new self();
 7     }
 8 }
 9 class B extends A
10 {
11 }
12 B::create();

会成功实例化B吗?不会的,并且还会报错


 

  Error: Cannot instantiate abstract class A in D:\wamp64\www\test.php on line 6


 

实际上,self对该类的作用与$this对对象的作用不完全相同。self不是指调用上下文,而是指解析上下文。因此,如果运行上面的例子,会报错,无法实例化抽象类

也就是说,self指向了定义了create()方法的A抽象类,而不是发送调用的B。在PHP5.3之前,这都是一种严格的限制,也出现了许多笨拙的解决方法。PHP5.3中引入了一种叫做延迟静态绑定的概念,最明显的特征就是关键字static。static与self类似,区别在于前者引用的是被调用的类。

这样写就能在静态上下文中利用继承关系了:

 1 <?php
 2 abstract class A
 3 {
 4     public static function create(): A
 5     {
 6         return new static();
 7     }
 8 }
 9 class B extends A
10 {
11 }
12 B::create();

2.

static关键字的用处可不止实例化而已。和self、parent一样,static还可以被用作静态方法调用的标识符,在非静态上下文中也一样。看代码:

A类中有分类group的概念,默认情况下是”default“类,我也可以在类的继承层次的分支中改变这个类别

 1 abstract class A
 2 {
 3     private $group;
 4     public function __construct()
 5     {
 6         $this->group = static::getGroup();
 7     }
 8     public static function create(): A
 9     {
10         return new static();
11     }
12     public static function getGroup()
13     {
14         return 'default';
15     }
16 }
17 
18 class B extends A
19 {
20 }
21 
22 class C extends A
23 {
24     public static function getGroup()
25     {
26         return 'document';
27     }
28 }
29 
30 class D extends C
31 {
32 }
33 var_dump(B::create(), C::create(), D::create());

我在A类中加入了一个构造方法,他会使用static关键字调用静态方法getGroup()。A类提供了“default”类别的实现。另外我还创建了一个新的类D,它继承自C。上面例子的输出结果为:


D:\wamp64\www\test.php:34:

object(B)[1]
  private 'group' 

(A)

 => 

string

 'default' (length=7)

D:\wamp64\www\test.php:34:

object(C)[2]
  private 'group' 

(A)

 => 

string

 'document' (length=8)

D:\wamp64\www\test.php:35:

object(D)[1]
  private 'group' 

(A)

 => 

string

 'document' (length=8)

对于D类,会先从被调用的D类自身开始找。由于它没有提供实现,C类中的getGroup()方法会被调用。

注意,假如把A类中 return new static() 改为 return new self(),那结果可就不一样了,就都会变成default了,因为使用self关键字的话,只有在实例化A(而不是D)时才能找到getGroup()

 

posted @ 2020-11-17 23:14  九鹤  阅读(129)  评论(0编辑  收藏  举报