PHP中如何形成static::与new static()的静态绑定

PHP中static::与new static()之后期静态绑定

一、parent、self、$this、__CLASS__

  1. class A {}
  2. class B extends A{
  3. parent::(public|protected)(静态方法|静态变量) ===> parent永远是A
  4. self::(public|protected)(静态方法|静态变量) ===> self永远是B
  5. $this->(public|protected)(非静态方法|非静态变量) ===> $this永远是B的是实例化对象
  6. __CLASS__ ===> 永远是B
  7. }
  8. class C extends B{
  9. parent::(public|protected)(静态方法|静态变量) ===> parent永远是B
  10. self::(public|protected)(静态方法|静态变量) ===> self永远是C
  11. $this->(public|protected)(非静态方法|非静态变量) ===> $this永远是C的是实例化对象
  12. __CLASS__ ===> 永远是C
  13. }

二、static::

static关键字可以实现以下功能:

1 调用类的静态方法 有后期静态绑定效果;

2 调用类的静态属性 有后期静态绑定效果;

3 调用类的非静态方法 没有后期静态绑定效果;

4 注意:不可以调用非静态属性;

  1. class A {
  2. private static function foo() {
  3. echo "A success!\n";
  4. }
  5. public function test() {
  6. $this->foo();
  7. }
  8. }
  9. class B extends A {
  10. }
  11. class C extends A {
  12. private static function foo() {
  13. echo "C success!\n";
  14. }
  15. }
  16. $b = new B();
  17. $b->test();//A success!
  18. $c = new C();
  19. $c->test();//A success!
  20. class A {
  21. private static function foo() {
  22. echo "A success!\n";
  23. }
  24. public function test() {
  25. static::foo();
  26. }
  27. }
  28. class B extends A {
  29. }
  30. class C extends A {
  31. private static function foo() {
  32. echo "C success!\n";
  33. }
  34. }
  35. $b = new B();
  36. $b->test();//A success!
  37. $c = new C();
  38. $c->test();//A无法调用C里的私有foo方法
  39. //将C的foo改成非private(public|protected)就可以解决
  40. class A {
  41. private static function foo() {
  42. echo "A success!\n";
  43. }
  44. public function test() {
  45. static::foo();
  46. }
  47. }
  48. class B extends A {
  49. }
  50. class C extends A {
  51. public static function foo() {
  52. echo "C success!\n";
  53. }
  54. }
  55. $b = new B();
  56. $b->test();//A success!
  57. $c = new C();
  58. $c->test();//C success!
  59. class A {
  60. public static function foo() {
  61. static::who();
  62. }
  63. public static function who() {
  64. echo __CLASS__."\n";
  65. }
  66. }
  67. class B extends A {
  68. public static function test() {
  69. A::foo();
  70. parent::foo();
  71. self::foo();
  72. }
  73. public static function who() {
  74. echo __CLASS__."\n";
  75. }
  76. }
  77. class C extends B {
  78. public static function who() {
  79. echo __CLASS__."\n";
  80. }
  81. }
  82. C::test();

A =>A::foo()的结果

C =>parent::foo()能走到A的foo,里面static::who找C::who

C =>self::foo()能走到B的foo,B继承A,走到A的foo,里面static::who找C::who

  1. class A {
  2. protected static function foo() {
  3. static::who();
  4. }
  5. protected static function who() {
  6. echo __CLASS__."\n";
  7. }
  8. }
  9. class B extends A {
  10. public static function test() {
  11. A::foo();
  12. parent::foo();
  13. self::foo();
  14. }
  15. protected static function who() {
  16. echo __CLASS__."\n";
  17. }
  18. }
  19. class C extends B {
  20. protected static function who() {
  21. echo __CLASS__."\n";
  22. }
  23. }
  24. C::test(); //A C C,解释同上
  25. class A {
  26. public static function foo() {
  27. static::who();
  28. }
  29. private static function who() {
  30. echo __CLASS__."\n";
  31. }
  32. }
  33. class B extends A {
  34. public static function test() {
  35. A::foo();
  36. parent::foo();
  37. // self::foo();
  38. }
  39. private static function who() {
  40. echo __CLASS__."\n";
  41. }
  42. }
  43. class C extends B {
  44. private static function who() {
  45. echo __CLASS__."\n";
  46. }
  47. }
  48. C::test();
  49. //A =>A::foo()的结果
  50. //报错 A不可C的私有方法who => parent::foo()能走到A的foo,里面static::who找C::who,C的who只能在C里调用,不能在A里调用
  51. //报错 A不可C的私有方法who => self::foo()能走到B的foo,B继承A,走到A的foo,里面static::who找C::who,C的who只能在C里调用,不能在A里调用

三、new static()

  1. //new self()与new static()的区别,官网例子如下:
  2. class A {
  3. public static function get_self() {
  4. return new self();
  5. }
  6. public static function get_static() {
  7. return new static();
  8. }
  9. }
  10. class B extends A {}
  11. echo get_class(B::get_self()); // A
  12. echo get_class(B::get_static()); // B
  13. echo get_class(A::get_static()); // A