热搜:NVER node 开发 php

关于后期静态绑定

2024-09-05 11:50:01
关于后期静态绑定

看了php手册中关于后期静态绑定,还是不太明白,原文地址 http://cn2.php.net/manual/zh/language.oop5.late-static-bindings.php

其中第四个例子

<?phpclass 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
当调用到parent::foo()和self::foo()时,为什么会调用C类的who()?
哪位朋友能解释一下,谢谢。


回复讨论(解决方案)

关于static操作符的解释:
后期静态绑定试图通过引入一个关键字表示运行时最初调用的类来绕过限制。
而这个最初调用的类就是C

A::foo(); 调用的是A类的方法,这你明白
self::foo(); // 这个self实际上是C类。明白吗? C::test() C继承了B的test()方法
parent::foo(); // 由于static::who(); 而不是self::who()。该方法调用的当前的类,也就是C类的foo()方法

也许你觉得还是弄不懂 A类中又为什么没有调用C的who()方法,这是由于parent的特殊关系。延迟静态绑定就是专门为了解决子类与父类间继承方法的问题才出现的。

也不必死记这个概念或者情景,当你遇到一个静态函数的继承与覆盖问题的时候,并发现它不是你想象中样子,那么你加上static再试一下成功了,就OK了。

个人感觉面向对象语言的特性比较个性化,而基本的东西无非封装,多态和继承,更多变态的特性一般是没有需求的,需求的时候也得考虑是不是可靠值得信赖。

手册不是说得很清楚么
------------------------------------------------------
”后期绑定“的意思是说,static::不再被解析为定义 当前方法所在的类,而是在实际运行时计算的。也可以称之为”静态绑定“,因为它可以用于(但不限于)静态方法的调用。
-------------------------------------------------------

#1说的有个小问题

self::foo(); // 这个self实际上是C类。明白吗? C::test() C继承了B的test()方法


不准确,self还是B类,但是本身没有覆写foo方法,所以就调用父类A的foo方法。
如果self实际是C类,那你试下self::foo();改成self::who();,应当打印C,但是打印B,这也正是self和static的区别。

谢谢纠正,学习了 手册不是说得很清楚么
------------------------------------------------------
”后期绑定“的意思是说,static::不再被解析为定义当前方法所在的类,而是在实际运行时计算的。也可以称之为”静态绑定“,因为它可以用于(但不限于)静态方法的调用。
----------------------------------------------……

A::foo();     //A指代A类,访问A类的foo方法和who方法
parent::foo();//调用B类的父类??A的foo方法,并告诉foo方法最原始的调用者是C
self::foo();  //self指代定义该方法的类,即B,但是B没有定义foo方法,它将原始的调用者C向上传递,
              // 访问父类的foo方法,最后访问c的who方法;


所以这就回答了三楼的疑问:若是把self::foo(); 改成self::who,因为self指代B,而B有who方法,所以结果是变成了B

静态调用使用 parent:: 或者 self:: 将转发原始调用信息。