猿问

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

输出结果为ACC.我的疑问是为什么第二个是C而不是B?还请各位大神赐教

呼如林
浏览 396回答 3
3回答

炎炎设计

自己来回答一下。静态调用分为转发调用和非转发调用。转发调用:进行静态调用时使用static::,self::,parent::,forword_static_call进行调用。换句话说就是没有指定类名的静态条用。非转发调用:进行静态调用时使用类名::或者进行非静态调用时使用类名->方法名调用。换句话说就是明确地指定类名的静态调用和非静态调用。 再说的通俗一点,顾名思义,非转发调用前面有类名所以调用的函数一定是属于“这个类的”,不需要转到别的类。转发调用就是由于前期的静态绑定导致在后面调用静态方法时可能“转发到其他的类”。 在PHP的官方文档里,对于后期静态绑定是这样说的:后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)中的类名。意思是当我们调用一个转发调用的静态调用时,实际调用的类是上一个非转发调用的类。现在我一步步分析上面的例子1.C::test().毫无疑问,这是一个非转发调用,因为::前面有类名C。2.进入test()方法,有三个静态调用A::foo(),parent::foo(),self::foo(),对于这三个静态调用来说,他们的非转发调用类就是C。3.现在执行A::foo(),这是一个非转发调用。A::foo()中的代码是static::who,这是一个转发调用,对于这个转发调用来说他的非转发调用类就是不再是C而是A(因为之前执行了A::foo())。因此执行的结果为A4.现在执行parent::foo(),这是一个转发调用,转发到哪里呢?就是它的上一个非转发调用的类,也就是类C(在步骤2中提到的)。在这里一定要注意虽然在这之前执行了A::foo(),但是parent::foo()的上一个非转发调用的类任然是类C。因此执行的结果是C.5.现在执行self::foo(),这个和parent::foo()一样都是转发调用,因此也输出C。

30秒到达战场

如果静态调用使用parent::或者 self::将转发调用信息,也就是运行时的调用者C

慕盖茨4494581

这就是静态调用static的意义啊.你用parent或者self会显示 当前调用者 , 也就是C .所以,才出现了static
随时随地看视频慕课网APP
我要回答