php 关于继承,面向对象 题目

1.网上看到一道题,没答案,自己执行了下,发现和自己想的不一样,新手求解惑
2.代码如下:

class A
{
    public static function foo()
    {
     static::who();
    }
    public static function who(){
        echo __CLASS__;
    }
}
class B extends A{
    public static function test()
    {
        A::foo();
        parent::foo();
        self::foo();
    }
    public static function who(){
        echo __CLASS__;
    }
}
class C extends B{
    public static function who(){
        echo __CLASS__;
    }
}
C::test();

3.输出结果为 ACC,求大神分析解答下

阅读 2.3k
2 个回答

因为后期静态绑定static是运行时计算的, 它会沿着调用栈向上回溯. 直到找到明确指定的类名.
回到例子, 对它进行简化, 排除掉一些干扰代码:

<?php 

class A
{
    public static function foo()
    {
     static::who();
    }
}
class B extends A{
    public static function test()
    {
        parent::foo();
    }
}
class C extends B{
    public static function who(){
        debug_print_backtrace();
        echo __CLASS__;
    }
}
C::test();

运行到static::who()时, 向上回溯, 发现调用者为parent::foo(), 因为parent是转发调用, 所以继续向上回溯, C::test(), C是明确的类名, 所以计算结果为C.

调用栈信息:

#0  C::who() called at [E:\123.php:7]
#1  A::foo() called at [E:\123.php:13]
#2  B::test() called at [E:\123.php:22]

看栈顶这行信息#0 C::who() called at [E:\123.php:7], static计算出的结果为类名C.

首先找到继承B的test()方法,先执行A中的foo,foo中又执行who,输出A
然后是parent的foo,相对于C的parent为B,所以又执行B的foo,里面执行static::who , 输出B
最后是执行C中的, 输出C

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题