PHP的静态成员以及self、$this和parent三者的区别

来源:互联网 发布:mac怎么设置屏幕 编辑:程序博客网 时间:2024/04/28 19:23

要搞清楚self和$this的区别,首先得理清楚静态成员这个基本概念。

类的静态成员用static关键字声明,是用来定义类的静态属性或方法,可以在类未被实例化时使用,静态成员属于类所有,而不属于某个具体的实例化对象,所以才可以在未实例化的时候使用。

self是对类本身的一个引用,$this是一个指向某个具体实例化的对象的指针。静态属性单独占用内存而不是随着对象的创建而动态开辟新的内存空间。

举例说明:

class Root{
     private static $name; //定义一个静态属性
     function __construct($n){
          self::$name=$n;
     }
    function say(){
        echo self::$name; 
    }
}

$p1 = new Root('xxxxx');
$p2 = new Root('yyyyy');

$p1->say(); //输出yyyy
$p2->say(); //输出yyyy

 

注意上面的结果,两个实例化的对象执行say()方法来输出静态属性$name的时候,输出的值是相同的。那是因为两个实例化对象的$name都是同一块内存空间里的东西。

$p1 = new Root('xxxxx'); 的时候 $name的值变成了xxxxx,但是$p2 = new Root('yyyyy'); 的时候$name的值成为了yyyyy,此时该内存空间保存的值就为yyyyy

另外一个例子:

class Root{
     private $name;   //定义一个非静态属性
     function __construct($n){
          $this->name=$n;
     }
    function say(){
        echo $this->name; 
    }
}

$p1 = new Root('xxxxx');
$p2 = new Root('yyyyy');

$p1->say(); //输出xxxxx
$p2->say(); //输出yyyyy

 

上面的结果是两次输出的值是不一样的,一次是xxxxx,一次是yyyyy,这是因为此时$name属性不是静态属性,那么每个实例化对象都会有自己的一个$name属性,开辟新的内存空间来存储它,而不是共同使用类的$name属性。

实例化了一百个Root的对象,那么就会开辟一百个空间来存储每个实例化对象的$name值。而static $name的时候始终都是指向同一个内存空间。

      需要注意的是:要访问静态成员,必须使用self来访问,不能使用$this来访问。因为self指向该类,$this指向某个具体的实例化对象,静态成员是属于该类的,而不是属于某个具体的实例化对象的。

同理: 要访问非静态成员,要使用$this而不能使用self。访问类的静态成员除了可以用self::静态成员,还可以使用 类名::静态成员 来访问。

     self和$this都能调用到父类的成员,不要被名字误导了,以为self只能访问到本类,不能放访问到父类的方法。同理的是,当父类的成员是静态成员要用self才能调用到,是非静态成员的时候要用$this才能调用的。

    此时可以发现self和$this的本质区别其实就是是否实例化的问题了,self可以在类未实例化的时候调用类的成员,而类的静态成员是独立分配内存空间的,类的非实例化成员是在类实例化的时候才为每个对象分配存储空间的,所有self只能调到独立分配存储空间的成员,$this只能调用实例化时动态分配存储空间的成员。

     

Php的parent和$this都可以用来调用父类的方法,区别在于,如果子类对父类方法进行了重载的话,parent调用到的是父类的方法,$this调用到的是重载后的方法

class Father{
     private $name='father';
     function say(){
         echo $this->name; 
     }
}

class Son extends Father{
     private $name='son';
     function say(){  //重载了基类的say()方法
        echo $this->name;
     }
    function fn1(){
      parent::say();  //用parent调用say()
    }
    function fn2(){
       $this->say();  //用$this调用say()
    }
}

$p1 = new Son();
$p1->fn1();  //输出 father
$p1->fn2(); //输出son

0 0
原创粉丝点击