PHP实战中知识总结 / 面向对象 - static关键字
一、static
static关键字是在类中描述成员属性和方法是静态的。static成员能够限制外部的访问,因为static成员是属于类的,不属于任何对象实例,是在类第一次被加载的时候分配的空间,其他类无法访问,只能对垒的实例共享,能对类的成员形成保护
静态成员是在类第一次加载的时候就创建的,所以在类的外部不需要对象而使用类名就可以访问的到静态的成员。
类里面的静态方法只能访问类的静态属性,不能访问类的非静态成员。在静态方法中可以通过使用 self::成员属性的方法进行访问。
静态属性不能通过一个类已实例化的对象来访问(但静态方法可以)。
<?
class Person
{
//下面是人的静态成员属性
public static $myCountry = "中国";
//这是人的静态成员方法
public static function say() {
echo "我是中国人";
}
}
//输出静态属性
echo Person::$myCountry;
//访问静态方法
Person::say();
(new Person())->say();
//重新给静态属性赋值
Person::$myCountry = "美国";
echo Person::$myCountry;
?>
二、静态变量与普通变量
在变量的前面加上static 就构成了静态变量(static 变量)。
1、静态变量:
(1)静态变量属于静态存储方式,其存储空间为内存中的静态数据区(在静态存储区内分配存储单元),该区域中的数据在整个程序的运行期间一直占用这些存储空间(在程序整个运行期间都不释放),也可以认为是其内存地址不变,直到整个程序运行结束。(在函数执行完后不会被销毁,保留上次值)
(2)静态变量虽在程序的整个执行过程中始终存在,但是在它作 用域之外不能使用。
(3)属于静态存储方式的变量不一定就是静态变量。 例如:外部变量(在PHP中指全局变量)虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。
2、静态局部变量
(1)static类型的内部变量是一种只能在某个特定函数中使用,只会被初始化一次。
(2)当在某函数里定义一个静态变量后,这个变量不会即使函数退出了,在下次调用这个函数时,它会使用前次被调用后留下的值。
(3)作用域为该函数内部,外部函数不能使用。
(4)局部静态变量定义时没有赋初值,系统会自动赋初值0(对数值型变量)或空字符(对字符变量)。
(5)局部静态变量占用内存时间较长,并且可读性差
3、全局局部变量
(1)全局变量(外部变量)的声明之前加上static 就构成了静态的全局变量。
(2)全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。
(3)静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。
4、普通变量
(1)非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。
(2)动态变量,属于动态存储类别,占动态存储空间,函数调用结束后即释放,不会保留上次函数运行的值。
// 静态局部变量:函数每次执行都会保留上次值
function static_test()
{
static $test = 0;
$test++;
echo $test;
}
static_test();// 第一次执行 输出 1
static_test();// 第二次执行 输出 2
// 普通局部变量:函数每次执行完都释放
function test()
{
$test = 0;
$test++;
echo $test;
}
test();// 第一次执行 输出 1
test();// 第二次执行 输出 1
把局部变量改变为静态变量后是改变了它的存储方式,即改变了它的生存期。
把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
三、静态方法与普通方法
1、静态方法
(1)静态和公共、受保护、私有这3种属性格式没有关系, 他们并不是并列的
(2)静态方法不需要通过对象即可调用,所以伪变量 $this 在静态方法中不可用
(3)在同一个类中可通过self::关键字来调用静态方法;不同类中,可以通过类的实例化对象来调用静态方法或者通过 类名::静态方法名的方式调用。
(4)类里面的静态方法只能访问类的静态属性,不能访问类的非静态成员。
(5)从程序运行开始就实例生成内存 ,会高很多,但静态内存是有限制的,实例太多会占用大量内存,且.静态内存会常驻
(6)适用于多次频繁调用
2、普通方法
(1)实例方法开始生成内存,执行效率相对于静态方法会慢很多
(2)普通方法不会常驻内存
(3)可以通过$this,self关键字来调用,即普通方法需要对象去调用,而静态方法不需要