PHP面向对象程序设计中的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的表现是一样的,可以替换为该类名::的方式调用。

  1. <?php
  2. class Demo{
  3. public static $static;
  4. public $Nostatic;
  5. public function __construct(){
  6. self::$static = "static";
  7. $this->Nostatic = "Nostatic";
  8. }
  9. public static function get(){
  10. return __CLASS__;
  11. }
  12. public function show(){
  13. return "this is function show with ".$this->Nostatic;
  14. }
  15. public function test(){
  16. echo Demo::$static."<br/>"; //使用类名调用静态属性
  17. echo Demo::get()."<br/>"; //使用类名调用静态属性
  18. echo Demo::show()."<br/>"; //使用类名调用静态属性
  19. echo self::$static."<br/>"; //self调用静态属性
  20. echo self::show()."<br/>"; //self调用非静态方法
  21. echo self::get()."<br/>"; //self调用静态方法
  22. echo static::$static."<br/>";//static调用静态属性
  23. echo static::show()."<br/>";//static调用非静态方法
  24. echo static::get()."<br/>"; //static调用静态方法
  25. }
  26. }
  27. $obj = new Demo();
  28. $obj->test();

输出结果:

  1. static
  2. Demo
  3. this is function show with Nostatic
  4. static
  5. this is function show with Nostatic
  6. Demo
  7. static
  8. this is function show with Nostatic
  9. Demo

继承的时候

在继承时,self和static在范围解析操作符 (::) 的使用上有差别。parent也是在继承的时候使用的。

  1. <?php
  2. class A{
  3. static function getClassName(){
  4. return "this is class A";
  5. }
  6. static function testSelf(){
  7. echo self::getClassName();
  8. }
  9. static function testStatic(){
  10. echo static::getClassName();
  11. }
  12. }
  13. class B extends A{
  14. static function getClassName(){
  15. return "this is class B";
  16. }
  17. }
  18. B::testSelf();
  19. echo "<br/>";
  20. B::testStatic();

输出结果:

this is class A

this is class B

self调用的静态方法或属性始终表示其在使用的时候的当前类(A)的方法或属性,可以替换为其类名,但是在类名很长或者有可能变化的情况下,使用self::的方式无疑是更好的选择。

static调用的静态方法或属性会在继承中被其子类重写覆盖,应该替换为对应的子类名(B)。

parent关键字用于调用父类的方法和属性。在静态方法中,可以调用父类的静态方法和属性;在非静态方法中,可以调用父类的方法和属性。

  1. <?php
  2. class A{
  3. public static $static;
  4. public $Nostatic;
  5. public function __construct(){
  6. self::$static = "static";
  7. $this->Nostatic = "Nostatic";
  8. }
  9. public static function staticFun(){
  10. return self::$static;
  11. }
  12. public function noStaticFun(){
  13. return "this is function show with ".$this->Nostatic;
  14. }
  15. }
  16. class B extends A{
  17. static function testS(){
  18. echo parent::staticFun();
  19. }
  20. function testNoS(){
  21. echo parent::noStaticFun();
  22. }
  23. }
  24. $obj = new B();
  25. $obj->testS();
  26. echo "<br/>";
  27. $obj->testNoS();

输出结果

static

this is function show with Nostatic

在文章的最后,我们分析一个手册上的例子

  1. <?php
  2. class A {
  3. public static function foo() {
  4. static::who();
  5. }
  6. public static function who() {
  7. echo __CLASS__."\n";
  8. }
  9. }
  10. class B extends A {
  11. public static function test() {
  12. A::foo();
  13. parent::foo();
  14. self::foo();
  15. }
  16. public static function who() {
  17. echo __CLASS__."\n";
  18. }
  19. }
  20. class C extends B {
  21. public static function who() {
  22. echo __CLASS__."\n";
  23. }
  24. }
  25. C::test();
  26. ?>

输出结果

A

C

C

我们单独拿出test方法进行分析:

  1. public static function test() {
  2. A::foo();
  3. parent::foo();
  4. self::foo();
  5. }

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)

  1. <?php
  2. class A {
  3. public static function foo() {
  4. static::who();
  5. }
  6. public static function who() {
  7. echo __CLASS__."\n";
  8. }
  9. }
  10. class B extends A {
  11. public static function test() {
  12. A::foo();
  13. parent::foo();
  14. self::foo();
  15. }
  16. public static function who() {
  17. echo __CLASS__."\n";
  18. }
  19. }
  20. class C extends B {
  21. // public static function who() {
  22. // echo __CLASS__."\n";
  23. // }
  24. }
  25. C::test();
  26. ?>

输出结果:

A B B

注2:补充解释上面的(3)

  1. <?php
  2. class A {
  3. public static function foo() {
  4. static::who();
  5. }
  6. public static function who() {
  7. echo __CLASS__."\n";
  8. }
  9. }
  10. class B extends A {
  11. public static function test() {
  12. A::foo();
  13. parent::foo();
  14. self::foo();
  15. }
  16. public static function foo() {
  17. echo "fooB"."\n";
  18. }
  19. public static function who() {
  20. echo __CLASS__."\n";
  21. }
  22. }
  23. class C extends B {
  24. public static function foo() {
  25. echo "fooC"."\n";
  26. }
  27. public static function who() {
  28. echo __CLASS__."\n";
  29. }
  30. }
  31. C::test();
  32. ?>

输出结果:A C fooB