PHP之后期静态绑定
PHP后期静态绑定的(late static bindings)
理解PHP延迟静态绑定
static::中的static其实是运行时所在类的别名,并不是定义类时所在的那个类名。这个东西可以实现在父类中能够调用子类的方法和属性。
使用(static)关键字来表示这个别名,和静态方法,静态类没有半毛钱的关系,static::不仅支持静态类,还支持对象(动态类)。
转发调用:
所谓的“转发调用”(forwarding call)指的是通过以下几种方式进行的静态调用,self::,parent::,static::以及forward_static_call()。
非转发调用
那么非转发调用其实就是明确指定类名的静态调用(foo::bar())和非静态调用($foo->bar())
后期静态绑定原理
后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwarding call)的类名。
例子1,简单实用static
class A
{
public static function who()
{
echo CLASS;
}
public static function test()
{
static::who();// 后期静态绑定从这里开始
}
}
class B extends A{
public static function who()
{
echo CLASS;
}
}
B::test();
以上程序会输出:
B
例子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();
以上程序会输出:
A C C
在这里主要分析下例子2。
1、C::test(),这是一个非转发调用,因为::前面有类名C。
2、进入test()方法,有三个静态调用A::foo(),parent::foo(),self::foo(),对于这三个静态调用来说,它们的非转发调用类就是C。
3、现在执行A::foo(),这是一个非转发调用。A::foo()中的代码是static::who(),这是一个转发调用,对于这个转发调用来说他的非转发调用类就是不再
是C而是A(因为之前执行了A::foo())。因此执行的结果为A。
4、现在执行parent::foo(),这是一个转发调用,转发到哪里呢?就是它的上一个非转发调用的类,也就是C
(在步骤2中提到的)。在这里一定要注意虽然在这之前执行了A::foo(),但是parent::foo()的上一个非转发调用的类任然是类C,
因此执行的结果是C。
5、现在执行self::foo(),这个和parent::foo()一样都是转发调用,因此也输出C。
使用后期静态绑定的好处
后期静态绑定目前我看到家多的是用于对象实例化中,在实例化对象时,static会根据运行时调用的类来决定实例化对象,
而self则是分局所在位置的类来决定实例化对象。当我们只想实例化子类,并且不希望后续再对子类的使用中由于父类的变化对
子类产生了影响时,后期静态绑定就能发挥它的作用了。
PHP之后期静态绑定的更多相关文章
- PHP的后期静态绑定
self 是个孝子 不管后来 谁是它的领导(调用它) 谁生了它 它就听谁的 子类调用父类的方法 self 的生存空间是父类 不管是不是子类调用 我生在哪 我就在哪个类里面找属性/方法 static ...
- php中的后期静态绑定
后期静态绑定PHP手册 使用的保留关键字: static 定义: static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的.也可以称之为"静态绑定",因为它可以用 ...
- php后期静态绑定
php后期静态绑定 自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类. 虽然也可以调用非静态方法,但是不会在运行时绑定. static 不再只是简 ...
- static后期静态绑定
先说一下__CLASS__,get_class() , get_called_class() 区别: __CLASS__获取当前的类名, get_class()与上面一样,都是获取当前的类名, ge ...
- 139-PHP static后期静态绑定(二)
<?php class test{ //创建test类 public function __construct(){ static::getinfo(); //后期静态绑定 } public s ...
- 138-PHP static后期静态绑定(一)
<?php class test{ //创建test类 public function __construct(){ self::getinfo(); //后期静态绑定 } public sta ...
- php中的后期静态绑定("Late Static Binding")
在我们以往中,在类中使用self关键字的时候都是指向了被调用方法定义时的类,而非原始的调用类. 例如: class Animal{ static $IQ_lv_avg = 1; public stat ...
- 父类方法返回子类实例:PHP延迟静态绑定
案例分析 先前的PHP项目中,看到类似于以下的一段代码: <?php class DBHandler { public function get() { } } class MySQLHandl ...
- 静态绑定 self 和 static的区别
后期静态绑定 自 PHP 5.3.0 起,PHP 增加了一个叫做后期静态绑定的功能,用于在继承范围内引用静态调用的类. 准确说,后期静态绑定工作原理是存储了在上一个“非转发调用”(non-forwar ...
随机推荐
- HashMap中的hash算法总结
前言 算法一直是我的弱项,然而面试中基本是必考的项目,刚好上次看到一个HashMap的面试题,今天也来学习下 HashMap中的hash算法是如何实现的. 数学知识回顾 << : 左移运算 ...
- 入门:移动APP中的各种导航
即使是移动应用界面的原型设计,导航的形式也可以多种多样.尽管尺寸小,又必须紧凑排列大量数据,它们似乎受到了紧密的约束,但依然有着形形色色的选择. 人们曾经一度只会考虑一种形式——流行且广泛使用的垂直导 ...
- 每日英语:Dashing the China Dream
Much has been said about what the 'China Dream' really means to many Chinese -- whether it is nation ...
- JUnit+Mockito结合测试Spring MVC Controller
[本文出自天外归云的博客园] 概要简述 利用JUnit结合Mockito,再加上spingframework自带的一些方法,就可以组合起来对Spring MVC中的Controller层进行测试. 在 ...
- MySQL中文参考手册
1 MySQL 的一般信息 这是MySQL参考手册:它记载了MySQL版本3.23.7-alpha. MySQL 是一个快速.多线程.多用户和强壮的SQL数据库服务器. 对Unix和 OS/2 平台, ...
- Go Revel - Testing(测试模块)
revel提供了一个测试框架来方便的为自己的程序编写功能测试用例. 默认创建的应用骨架附带一个简单的测试用例,这里将它作为起点 ##概览 测试保存在`tests`目录: corp/myapp app/ ...
- Java知多少(24)包装类、拆箱和装箱详解
虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备“对象”的特性——不携带属性.没有方法可调用. 沿用它们只是为了迎合人类根深蒂固的习惯, ...
- 关于Unity的两种调试方法
Unity的两种调试方法 1.Debug.Log()输出语句调试,平时经常用这个 2.把MonoDevelop和Unity进行连接后断点调试 先把编辑器选择为MonoDevelop,Edit----& ...
- vector、map 内存释放
一.vector void TestVector() { cout << "begin create vector" << endl; int iSize ...
- Thinkphp5 关联模型
必须建立两个模型分类模型(attr).文章模型(article) attr模型 <?php namespace app\common\model; use think\Model; class ...