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 相关文章推荐
一个php作的文本留言本的例子(四)
Oct 09 PHP
PHP通过COM使用ADODB的简单例子
Dec 31 PHP
php 远程图片保存到本地的函数类
Dec 08 PHP
php小偷相关截取函数备忘
Nov 28 PHP
114啦源码(114la)不能生成地方房产和地方报刊问题4级页面0字节的解决方法
Jan 12 PHP
PHP文章采集URL补全函数(FormatUrl)
Aug 02 PHP
记录PHP错误日志 display_errors与log_errors的区别
Oct 09 PHP
php获取QQ头像并显示的方法
Dec 23 PHP
php生成唯一的订单函数分享
Feb 02 PHP
PHP面向对象编程之深入理解方法重载与方法覆盖(多态)
Dec 24 PHP
thinkPHP框架实现生成条形码的方法示例
Jun 06 PHP
使用laravel指定日志文件记录任意日志
Oct 17 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操作xml代码
2010/06/17 PHP
php简单对象与数组的转换函数代码(php多层数组和对象的转换)
2011/05/18 PHP
php中的一些数组排序方法分享
2012/07/20 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
两种简单实现菜单高亮显示的JS类代码
2010/06/27 Javascript
jQuery getJSON()+.ashx 实现分页(改进版)
2013/03/28 Javascript
jqeury-easyui-layout问题解决方法
2014/03/24 Javascript
JavaScript语言对Unicode字符集的支持详解
2014/12/30 Javascript
老生常谈遮罩层 滚动条的问题
2016/04/29 Javascript
Javascript将数字转化成为货币格式字符串
2016/06/22 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
2016/07/05 Javascript
完美解决spring websocket自动断开连接再创建引发的问题
2017/03/02 Javascript
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
微信小程序实现移动端滑动分页效果(ajax)
2017/06/13 Javascript
vuejs前后端数据交互之从后端请求数据的实例
2018/08/11 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
js 实现碰撞检测的示例
2020/10/28 Javascript
Vue——前端生成二维码的示例
2020/12/19 Vue.js
python实现矩阵乘法的方法
2015/06/28 Python
使用Python的Flask框架构建大型Web应用程序的结构示例
2016/06/04 Python
深度定制Python的Flask框架开发环境的一些技巧总结
2016/07/12 Python
Python实现备份MySQL数据库的方法示例
2018/01/11 Python
Python函数any()和all()的用法及区别介绍
2018/09/14 Python
对pandas里的loc并列条件索引的实例讲解
2018/11/15 Python
Python3实现获取图片文字里中文的方法分析
2018/12/13 Python
Django mysqlclient安装和使用详解
2020/09/17 Python
校园文明标语
2014/06/13 职场文书
2014年销售工作总结范文
2014/12/01 职场文书
物流业务员岗位职责
2015/04/03 职场文书
2016新年致辞
2015/08/01 职场文书
大学体育课感想
2015/08/10 职场文书
2016年学校党支部创先争优活动总结
2016/04/05 职场文书
选择比努力更重要?这是长期以来对“努力”的最大误解
2019/07/12 职场文书
高端收音机+蓝牙音箱,JBL TUNER FM带收音蓝牙音箱评测
2021/04/24 无线电
pytorch 如何使用batch训练lstm网络
2021/05/28 Python
SQL中的三种去重方法小结
2021/11/01 SQL Server