php static self 应该要掌握的区别
作者:
秒速五厘米
php static 和 self 都可以调用类中静态的属性和方法,但是他们还是具备一些本质上的不同,稍微不注意就会酿成程序逻辑错误,做个记录。
两者相同的时候
class A{ public static $ask="hello"; public function GetAsk(){ echo get_called_class()."<br/>"; echo self::$ask; } } $b= new A(); $b->GetAsk();
class A{ public static $ask="hello"; public function GetAsk(){ echo get_called_class()."<br/>"; echo static::$ask; } } $b= new A(); $b->GetAsk();
两者输出的内容都是相同:A以及hello。
可见 当两者在非继承情况下,表现得一致。
两者展现差异的时候
class A{ public static $ask="hello"; public function GetAsk(){ echo get_called_class()."<br/>"; echo self::$ask;//hello echo static::$ask; } } class B extends A{ public static $ask="nihao"; public function GetNIhao(){ echo self::$ask; echo static::$ask; } } $b= new B(); $b->GetNIhao(); // 都输出 nihao
class A{ public static $ask="hello"; public function GetAsk(){ echo get_called_class()."<br/>"; echo self::$ask; //hello echo static::$ask; //nihao } } class B extends A{ public static $ask="nihao"; public function GetNIhao(){ echo self::$ask; echo static::$ask; } } $b= new B(); $b->GetAsk(); //
这个时候,static输出“nihao”,self输出“hello”。
我们可以看到 static 表示维持,self代表定义。
总结
static始终会维持调用者内存地址,上面代码中static始终指向$b所代表的的实例对象,在运行的时候就会优先去 本身类的定义域中去寻找存不存在该变量。
self就很粗暴,不管你是哪个类,它只看被调用的方法或者属性变量定义在哪里,比如定义在父类($ask),那self就代表父类的地址引用。
所以static表示维持(维持调用者指针),self代表本身(定义者)。
还有一点:
new static / new self 他们之间的区别
一样的原则:static维持,self定义。
new操作符会产生一个新的实例对象,那么问题就是,到底是哪个类的实例?
当我们没得选的时候,他们表现的一致(没有继承的情况下)。
当存在继承,static看谁在调用,self看呗调用的变量或者方法定义在哪里。
这一切讨论的前提是:面向对象。