🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
**new self()与new static()** ``` new static 和 new self 都是实例化当前类, ``` 但是new static实例化所在的类,子类如果没有重写的话那么实例化的就是父类。 而new self就是严格的代码里的当前类 两者都是实例化自身,区别在于继承。如果没有继承,则两者返回的实例都是属于一个类;如果有继承,子类调用该方法,`new self`仍然返回原类的实例,而`new static`返回实际子类的实例。这就是延迟静态绑定,static 的值,使用的是最后实际调用那个方法的类。 在函数返回值中有个@return static 表示的就是返回 new self对象 * * * ~~~ class ATest { public function say() { echo 'Segmentfault'; } public function callSelf() { self::say(); } public function callStatic() { static::say(); } } class BTest extends ATest { public function say() { echo 'PHP'; } } $b = new BTest(); $b->say(); // output: php:say方法被子类覆盖了所以输出PHP $b->callSelf(); // output: segmentfault:继承的是父类的方法和属性 $b->callStatic(); // output: php ~~~ self::属性|方法 与 static::属性|方法区别 self::属性|方法调用的一定是当前类的如果子类没有覆盖父类才是父类的但是从另一个角度来说继承父类的其实还是调用当前子类的 static::属性|方法 后期静态绑定 ``` class A { public static function who() { echo __CLASS__;//A } public static function test() { self::who();//A } } class B extends A { public static function who() { echo __CLASS__; } } B::test();//A test在A定义 ``` \--------------------------------------------------------下面的知识前必须知道------------------------------------------------------- class A { public function demo(){ echo \_\_CLASS\_\_; } } class B extends A { } $obj = new B; $obj->demo();//A 注意:继承的话是继承的父类的全部东西跟子类没关系 使用 *self::* 或者 *\_\_CLASS\_\_* 对当前类的静态引用,取决于定义当前方法所在的类: \------------------------------------------------------ class A { public static function who() { echo \_\_CLASS\_\_;//A } public static function test() { static::who();// 后期静态绑定从这里开始 } } class B extends A { public static function who() { echo \_\_CLASS;//B } } B::test();//B static能够让你在上述例子中调用 *test()* 时引用的类是 *B* 而不是 *A* 后期静态绑定本想通过引入一个新的关键字表示运行时最初调用的类来绕过限制。简单地说,这个关键字能够让你在上述例子中调用 *test()* 时引用的类是 *B* 而不是 *A*。最终决定不引入新的关键字,而是使用已经预留的 *static* 关键字。 *static也能对非静态环境下的类进行操作* class A { private function foo() { echo "success!\\n"; } public function test() { $this->foo(); static::foo(); } } class B extends A { /\* foo() 将复制到 B, 因此它的范围(作用域)任然是 A和调用成功\*/ } class C extends A { private function foo() { /\* 原来的方法被替代; 实例的范围是 C \*/ } } $b = new B(); $b->test(); $c = new C(); $c->test(); //fails /\*success! success! success! Fatal error: Call to private method C::foo() from context 'A' in D:\\xampp\\htdocs\\phpceshi.php on line 9 \*/ 注意:在非静态环境下,所调用的类即为该对象实例所属的类。由于 *$this->* 会在同一作用范围内尝试调用私有方法,而 *static::* 则可能给出不同结果。另一个区别是 *static::* 只能用于静态属性。 \----------------------------------------------------------------------------------------------------------------- 后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,如果静态调用使用 *parent::* 或者 *self::* 将转发调用信息。 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();//输出A C C ```