PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定


Posted in PHP onJune 12, 2014

Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定。

1、静态变量 static variable

静态变量仅在局部函数域中存在,但当程序执行离开此作用域时,其值并不丢失。也就是说,在下一次执行这个函数时,变量仍然会记得原来的值。要将某个变量定义为静态的,只需要在变量前加上static关键字即可。

function testing()
{
    static $a = 1;
    $a *= 2;
    echo $a."\n";
}
testing();
testing();
testing();
testing();
/**
 *    2
 *    4
 *    8
 *    16
 *    [Finished in 0.1s]
*/

静态变量也提供了一种处理递归函数的方法。递归函数是一种调用自己的函数。写递归函数时要小心,因为可能会无穷递归下去。必须确保有充分的方法来中止递归。

本例中 testing()函数在每次执行之后,都会在内部保存 $a 变量的值。在下一次 testing()函数被调用时,$a 的值就会恢复,然后 testing() 函数会将这个值乘以2,并打印。变量的初始默认值为1,这一赋值操作只会在变量第一次被初始化时发生。函数每次执行的过程中,这一操作不会被调用。

2、类中静态元素的使用

在类中 static 关键字有两种主要的用法,一种是用来定义静态成员,另一种是用来定义静态方法。声明类属性或方法为静态,就可以不实例化类而直接访问。静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。静态属性不可以由对象通过 -> 操作符来访问。在类的内部我们可以使用作用域限定操作符来访问不同层次作用域的变量。

2.1、静态属性

由于静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用。可以把静态变量看成是属于整个类而不是属于类的某个实例。与一般的实例变量不同的是,静态属性只保留一个变量值,而这个变量值对所有的实例都有效,也就是说所有实例共享这一个属性。

class MyObject
{
    public static $a = 0;
    function MyMethod()
    {
        self::$a += 2;
        echo self::$a . "\n";
    }
}
$instance1 = new MyObject();
$instance1 -> MyMethod();
$instance2 = new MyObject();
$instance2 -> MyMethod();
/**
 *
 * 2
 * 4
 * [Finished in 0.1s]
 *
 */

$this 指标是类的当前实例,是一个到主叫对象的引用。

self:: 表示的是类本身,使用 self:: 作用域限定符时必须在操作符后面加上 $ 符号,在类之外的代码中不能使用这个操作符,而且它不能识别自己在继承树层次结构中的位置。在扩展类中使用 self:: 作用域时, self 可以调用基类中声明的方法,但它调用的总是已经在扩展类中重写的方法。

parent:: 在扩展类中,在基类的方法被重写的情况下,如果你要访问基类的方法,可以使用 parent::

static:: 使我们不再需要使用 self:: 和 parent:: 。当希望指向最终的实现功能的类时,就可以使用static,这个限定符会在代码执行之前立即计算出继承层次结构上最后那个类的成员。

2.3、静态方法

静态方法的规则和静态变量是相同的。使用static关键字可以将方法标记为静态方法,而通过类的名称 和 作用域限定操作符 (::)可以访问静态方法。

静态方法和非静态方法之间有一个很重要的区别:在调用静态方法时,我们不在需要拥有类的实例。

class MyObjectBase
{
    static function MyMethod()
    {
        static::MyOtherMethod();
    }
    static function MyOtherMethod()
    {
        echo 'called from MyObject.';
    }
}
class MyExtendObject extends MyObjectBase
{
    static function MyOtherMethod()
    {
        echo 'called from MyExtendObject.';
    }
}
MyExtendObject::MyMethod();

上例代码会正确的调用MyExtendObject中的 MyOtherMethod 方法,输出 called from MyExtendObject. [Finished in 0.1s]。

如果某个方法中不包含$this 变量,那么这个方法就应该是静态方法。如果不需要类的实例,那么还应该使用静态类,这样可以免去实例化的工作。另外,在静态方法中是不能使用 $this 变量的,因为静态方法不属于某个特定的实例。

2.4、延迟绑定

static:: 使我们不再需要使用 self:: 和 parent:: 。当希望指向最终的实现功能的类时,就可以使用static,这个限定符会在代码执行之前立即计算出继承层次结构上最后那个类的成员。这一过程被称作延迟绑定。

3、总结

使用static关键字可以创建静态变量,同时还可以提供一个默认的初始化值。静态变量是经过修饰的函数变量,在某个函数执行完成之后,他的值仍保持不丢失。

static关键字还可以用在类中来修饰属性和方法。用在属性上时,它使属性不再为某个实例保存一个值,而是为整个类自身保存一个值,静态属性可以在成员间共享。

要访问静态方法可以用(::),它被称作作用域限定符。这个操作符的左边可以是一个类名或者某个预定义作用域,预定义作用域包括 self parent static。操作符的右边是一个静态方法、属性。

PHP 相关文章推荐
模板引擎Smarty深入浅出介绍
Dec 06 PHP
一个php导出oracle库的php代码
Apr 20 PHP
PHP时间格式控制符对照表分享
Jul 23 PHP
PHP循环结构实例讲解
Feb 10 PHP
ThinkPHP惯例配置文件详解
Jul 14 PHP
php实现阿拉伯数字和罗马数字相互转换的方法
Apr 17 PHP
PHP实现仿Google分页效果的分页函数
Jul 29 PHP
PHP弹出对话框技巧详细解读
Sep 26 PHP
php自定义中文字符串截取函数substr_for_gb2312及substr_for_utf8示例
May 28 PHP
PHP回调函数与匿名函数实例详解
Aug 16 PHP
基于PHP常用文件函数和目录函数整理
Aug 17 PHP
PHP实现模拟http请求的方法分析
Dec 20 PHP
PHP 面向对象程序设计(oop)学习笔记(一) - 抽象类、对象接口、instanceof 和契约式编程
Jun 12 #PHP
对PHP语言认识上需要避免的10大误区
Jun 12 #PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
Jun 12 #PHP
PHP微框架Dispatch简介
Jun 12 #PHP
PHP资源管理框架Assetic简介
Jun 12 #PHP
探寻PHP脚本不报错的原因
Jun 12 #PHP
在PHP中运行Linux命令并启动SSH服务的例子
Jun 12 #PHP
You might like
php微信开发之批量生成带参数的二维码
2016/06/26 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
php实现URL加密解密的方法
2016/11/17 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
dotopAlert 提示用户需安装播放器的代码
2012/09/17 Javascript
解决火狐浏览器下JS setTimeout函数不兼容失效不执行的方法
2012/11/14 Javascript
深入理解javascript的执行顺序
2014/04/04 Javascript
jquery实现右键菜单插件
2015/03/29 Javascript
纯js实现仿QQ邮箱弹出确认框
2015/04/29 Javascript
JS实用的动画弹出层效果实例
2015/05/05 Javascript
javascript 闭包详解
2015/07/02 Javascript
jquery实现简单的banner轮播效果【实例】
2016/03/30 Javascript
微信小程序 保留小数(toFixed)详细介绍
2016/11/16 Javascript
JS 实现计算器详解及实例代码(一)
2017/01/08 Javascript
angular实现form验证实例代码
2017/01/17 Javascript
angularjs ui-router中路由的二级嵌套
2017/03/10 Javascript
详解用vue-cli来搭建vue项目和webpack
2017/04/20 Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
2017/05/17 Javascript
webpack打包单页面如何引用的js
2017/06/07 Javascript
微信小程序图片自适应支持多图实例详解
2017/06/21 Javascript
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
关于JS解构的5种有趣用法
2019/09/05 Javascript
详解如何在JS代码中消灭for循环
2019/12/11 Javascript
JavaScript变量Dom对象的所有属性
2020/04/30 Javascript
python发送邮件示例(支持中文邮件标题)
2014/02/16 Python
python多线程编程中的join函数使用心得
2014/09/02 Python
Python实现简单的文本相似度分析操作详解
2018/06/16 Python
pygame游戏之旅 添加游戏暂停功能
2018/11/21 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
Python assert关键字原理及实例解析
2019/12/13 Python
Python 发送邮件方法总结
2020/08/10 Python
python获取linux系统信息的三种方法
2020/10/14 Python
python 列表推导和生成器表达式的使用
2021/02/01 Python
幼师辞职信怎么写
2015/02/27 职场文书
MySQL sql_mode修改不生效的原因及解决
2021/05/07 MySQL
Python借助with语句实现代码段只执行有限次
2022/03/23 Python