這篇文章主要介紹了PHP面向對象程序設計中的self、static、parent關鍵字用法,結合實例形式分析了self、static、parent關鍵字功能、應用場景及相關使用技巧,須要的朋友能夠參考下,本文實例講述了PHP面向對象程序設計中的self、static、parent關鍵字用法.分享給你們供你們參考,具體以下:
看到php裏面有關於後期靜態綁定的內容,雖然沒有徹底看懂,可是也收穫很多東西。
不存在繼承的時候,不存在繼承的意思就是,就書寫一個單獨的類來使用的時候。self和static在範圍解析操做符 (::) 的使用上,並沒有區別。
在靜態函數中,self和static能夠調用靜態屬性和靜態函數(沒有實例化類,所以不能調用非靜態的屬性和函數)。
在非靜態函數中,self和static能夠調用靜態屬性和靜態函數以及非靜態函數
此時,self和static的表現是同樣的,能夠替換爲該類名的方式調用。php
<?php class Demo{ public static $static; public $Nostatic; public function __construct(){ self::$static = "static"; $this->Nostatic = "Nostatic"; } public static function get(){ return __CLASS__; } public function show(){ return "this is function show with ".$this->Nostatic; } public function test(){ echo Demo::$static."<br/>"; //使用類名調用靜態屬性 echo Demo::get()."<br/>"; //使用類名調用靜態屬性 echo Demo::show()."<br/>"; //使用類名調用靜態屬性 echo self::$static."<br/>"; //self調用靜態屬性 echo self::show()."<br/>"; //self調用非靜態方法 echo self::get()."<br/>"; //self調用靜態方法 echo static::$static."<br/>";//static調用靜態屬性 echo static::show()."<br/>";//static調用非靜態方法 echo static::get()."<br/>"; //static調用靜態方法 } } $obj = new Demo(); $obj->test();
輸出結果;ide
static Demo this is function show with Nostatic static this is function show with Nostatic Demo static this is function show with Nostatic Demo
繼承的時候
在繼承時,self和static在範圍解析操做符 (::) 的使用上有差異。parent也是在繼承的時候使用的。函數
<?php class A{ static function getClassName(){ return "this is class A"; } static function testSelf(){ echo self::getClassName(); } static function testStatic(){ echo static::getClassName(); } } class B extends A{ static function getClassName(){ return "this is class B"; } } B::testSelf(); echo "<br/>"; B::testStatic();
輸出結果:this
this is class A this is class B
self調用的靜態方法或屬性始終表示其在使用的時候的當前類(A)的方法或屬性,能夠替換爲其類名,可是在類名很長或者有可能變化的狀況下,使用self::的方式無疑是更好的選擇。
static調用的靜態方法或屬性會在繼承中被其子類重寫覆蓋,應該替換爲對應的子類名(B)。
parent關鍵字用於調用父類的方法和屬性。在靜態方法中,能夠調用父類的靜態方法和屬性;在非靜態方法中,能夠調用父類的方法和屬性。設計
<?php class A{ public static $static; public $Nostatic; public function __construct(){ self::$static = "static"; $this->Nostatic = "Nostatic"; } public static function staticFun(){ return self::$static; } public function noStaticFun(){ return "this is function show with ".$this->Nostatic; } } class B extends A{ static function testS(){ echo parent::staticFun(); } function testNoS(){ echo parent::noStaticFun(); } } $obj = new B(); $obj->testS(); echo "<br/>"; $obj->testNoS();
輸出結果;code
static this is function show with Nostatic
在文章的最後,咱們分析一個手冊上的例子對象
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function who() { echo __CLASS__."\n"; } } C::test(); ?>
輸出結果繼承
A C C
咱們單獨拿出test方法進行分析:get
public static function test() { A::foo(); parent::foo(); self::foo(); }
1)A::foo();這個語句是能夠在任何地方執行的,它表示使用A去調用靜態方法foo()獲得'A'。
2)parent::foo();C的parent是B,B的parent是A,回溯找到了A的foo方法;static::who();語句中的static::調用的方法會被子類覆蓋,因此優先調用C的who()方法,若是C的who方法不存在會調用B的who方法,若是B的who方法不存在會調用A的who方法。因此,輸出結果是'C'。[注1]
3)self::foo();這個self::是在B中使用的,因此self::等價於B::,可是B沒有實現foo方法,B又繼承自A,因此咱們實際上調用了A::foo()這個方法。foo方法使用了static::who()語句,致使咱們又調用了C的who函數。[注2]it
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function who() { echo __CLASS__."\n"; } } class C extends B { // public static function who() { // echo __CLASS__."\n"; // } } C::test(); ?>
輸出結果:
A B B
注2:補充解釋上面的(3)
<?php class A { public static function foo() { static::who(); } public static function who() { echo __CLASS__."\n"; } } class B extends A { public static function test() { A::foo(); parent::foo(); self::foo(); } public static function foo() { echo "fooB"."\n"; } public static function who() { echo __CLASS__."\n"; } } class C extends B { public static function foo() { echo "fooC"."\n"; } public static function who() { echo __CLASS__."\n"; } } C::test(); ?>
輸出結果:
A C fooB