延迟静态绑定是在php5.3中出现的一个概念,那么为什么会有这样一个东东呢?我们可以先来看看下面这个示例代码:
class ClassA{ static public $a = ‘I am ClassA‘;//定义一个静态变量$a public function getClassName() { return self::$a; } } class ClassB extends ClassA { static public $a = ‘I am ClassB‘; } //实例化一个ClassB的对象 $b = new ClassB(); echo $b->getClassName();//输出 ‘I am ClassA’
看到输出结果不知道你会不会有这样一个疑问:为啥我实例化的是ClassB类的对象$b,调用getClassName方法时,返回的应该是我在类ClassB定义的属性$a,即最终输出‘I am ClassB’才对?
其实之所以没有按照我们的预期那样输出结果,是因为我们在方法getClassName中使用了self关键字,self指代的是解析上下文,即哪个类中的方法包含了self,它就指代那个类本身,所以我们调用self::$a时,它的值为ClassA类中的属性$a的值。
需求:那么如果我想要通过实例化出的$b对象调用getClassName方式时使用的是ClassB中的属性$a呢?
方法1:我们可以在类ClassB中覆盖父类ClassA的getClassName方法,直接copy方法到ClassB即可。
方法2:用到我们今天要介绍的延迟静态绑定,用法就是将getClassName方法中的self关键字替换成static关键字,他们区别在于static引用的是被调用的类,即使用static的方法被哪个类调用,就指代这个类本身,而self指代的是包含类(我写在哪个类就是指代那个类),代码如下
class ClassA{ static public $a = ‘I am ClassA‘; public function getClassName() { return static::$a;//这里将self改为了static } } class ClassB extends ClassA { static public $a = ‘I am ClassB‘; } //实例化一个ClassB的对象 $b = new ClassB(); echo $b->getClassName();//输出 ‘I am ClassB’
我们刚接触时要花点时间好好理解下self和static的作用和区别,还要知道静态变量和静态方法的作用;
利用延迟静态绑定这个原理,我们可以在定义一个类时为其本身或者它的子类创建一个“工厂方法”,这样我们就不用每次在实例化一个对象的时候使用 new 类名() 的形式了,当然这样的方式还是看具体项目的需求的哈
class School{ protected $name = ‘‘; public function __construct(string $n) { $this->name = $n; } //用于实例化对象的工厂方法 public static function create(string $n) : School { return new static($n); } public function getName() { return $this->name; } } class Classroom extends School{ } class Library extends School{ } $classroom_obj = Classroom::create(‘classroom 1‘); var_dump($classroom_obj);//object(Classroom)#1 (1) { ["name":protected]=> string(11) "classroom 1" } $library_obj = Library::create(‘center library‘); var_dump($library_obj);//object(Library)#2 (1) { ["name":protected]=> string(14) "center library" }
好啦,今天关于static的一丢丢知识点就分享到这里啦,如有不正确的地方请多多指正,感谢~