一.self:: 的限制:

在一个类的方法使用 self:: 或者是 __CLASS__ 对当前类的静态属性,或者方法(静态方法非静态方法都可以),取决与当前方法所在的类,如果如果当前类中不存在调用的类或者是方法,如果它又父类,则向上在它的父类中查找,直到找到为止。

//实例代码1
<?php
class A{
    const CURRENT = 'A';
    const A = 'A';
}
class B extends A{
    const CURRENT = 'B';
    public function get(){
        echo self::CURRENT.PHP_EOL.self::A; //这儿用的self关键字
    }
}
class C extends B{
    const CURRENT = 'C';
}
$b = new C();
$b->get();
PHP

运行得到的结果:

$ php selfBind.php
B
A

二.静态延迟绑定的用法。

静态延迟绑定本想通过引入一个新的关键字表示运行时最初调用的类来绕过限制。用上边的例子来说就是 $b->get() 获得的当前 CURRENT 属性的值是 C。最终决定不引入新的关键字,而是使用已经预留的 static 关键字。

1.基本用法

在一个类中使用 static 来调用静态属性或者是方法(静态方法,非静态方法都可以),取决与当前的类的属性或者方法。如果当前的类没有,并且它有父类,那么则向上去父类查找。

//实例代码2
<?php
class A{
    const CURRENT = 'A';
    const A = 'A';
}
class B extends A{
    const CURRENT = 'B';
    public function get(){
        echo static::CURRENT.PHP_EOL.static::A; //这儿用的static关键字
    }
}
class C extends B{
    const CURRENT = 'C';
}
$b = new C();
$b->get();
PHP

运行得到的结果

$ php selfBind.php
C
A

注意,我把这个时候获得的 CURRENT 属性值就是当前实例化的属性值 C

2.如果静态调用使用 parent:: 或者 self:: 将转发调用信息。

<?php
class A{
    public static function current(){
        echo __CLASS__.PHP_EOL;
    }

    public static function foo(){
        static::CURRENT();
    }
}
class B extends A{

    public function test(){
        A::foo();
        parent::foo(); //parent::会转发调用信息,所以父类中的调用的CURRENT()方法是当前实例化C的CURRENT()方法
        self::foo(); //self::也会转发调用信息,所以父类中的调用的CURRENT()方法是当前实例化C的CURRENT()方法
    }

    public static function current(){
        echo __CLASS__.PHP_EOL;
    }
}
class C extends B{
    public static function current(){
        echo __CLASS__.PHP_EOL;
    }
}
$b = new C();
$b->test();
PHP

运行得到的结果

$ PHP selfBind.php
A
C
C

总结

  • 静态方法中只能调用静态变量或者静态方法,非静态方法中可以调用非静态方法、非静态属性、静态属性、静态方法,还能用 static 调用非静态方法 。
  • self:: 调用类的静态属性或者是方法,最终取决于 self:: 所在的类,如果 self:: 所在的类没有,则向上查找。
  • static: 调用类的静态属性或者是方法,最终取决于当前的调用类,如果当前调用的类没有,则向上查找。
  • parent:: 和 self:: 会转发调用信息。
相关评论(0)
您是不是忘了说点什么?

友情提示:垃圾评论一律封号...

还没有评论,快来抢沙发吧!