PHP面向对象编程之延迟静态绑定(static关键字)

Posted charleychan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP面向对象编程之延迟静态绑定(static关键字)相关的知识,希望对你有一定的参考价值。

延迟静态绑定是在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的一丢丢知识点就分享到这里啦,如有不正确的地方请多多指正,感谢~

 

以上是关于PHP面向对象编程之延迟静态绑定(static关键字)的主要内容,如果未能解决你的问题,请参考以下文章

php面向对象编程笔记static的后期静态绑定

PHP延迟静态绑定:static关键字

PHP "延迟静态绑定" 功能,static

PHP延迟静态绑定

PHP M题2

PHP面向对象编程简单实例