PHP面向對象程序設計中的self、static、parent關鍵字用法分析

 更新時間:2019年08月14日 09:44:19   作者:koastal   我要評論
這篇文章主要介紹了PHP面向對象程序設計中的self、static、parent關鍵字用法,結合實例形式分析了self、static、parent關鍵字功能、應用場景及相關使用技巧,需要的朋友可以參考下

本文實例講述了PHP面向對象程序設計中的self、static、parent關鍵字用法.分享給大家供大家參考,具體如下:

看到php里面有關于后期靜態綁定的內容,雖然沒有完全看懂,但是也收獲不少東西。

php官方手冊介紹:
http://php.net/manual/zh/language.oop5.late-static-bindings.php

不存在繼承的時候

不存在繼承的意思就是,就書寫一個單獨的類來使用的時候。self和static在范圍解析操作符 (::) 的使用上,并無區別。

  • 在靜態函數中,self和static可以調用靜態屬性和靜態函數(沒有實例化類,因此不能調用非靜態的屬性和函數)。
  • 在非靜態函數中,self和static可以調用靜態屬性和靜態函數以及非靜態函數

此時,self和static的表現是一樣的,可以替換為該類名::的方式調用。

<?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();

輸出結果:

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 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();

輸出結果

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方法進行分析:

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]

注1:補充解釋上面的(2)

<?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

更多關于PHP相關內容感興趣的讀者可查看本站專題:《php面向對象程序設計入門教程》、《PHP數組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總

希望本文所述對大家PHP程序設計有所幫助。

相關文章

最新評論

2019开奖结果