php中self,this, parent 详解

1、前言

self,this,parent 这三个关键字在 类的使用中可谓屡见不鲜,那么这三个关键字又有什么区别;
从字面意思理解:

  • this  是指向当前类(就近原则,离谁近跟谁)
  • self  是指向当前类(一般是静态变量,静态方法用,指本身)
  • parent是指向父类(php是单继承,父类也就只有一个)

2、this 关键字

测试类如下:

<?php
declare (strict_types = 1);
class A 
{
    public $name;
    function setName(string $name) 
    {
        $this->name = $name;
    }
    function getName()
    {
        var_dump($this->name);
    }
}

class B extends A
{    
    //这里B继承A但是不做任何操作,
    //B也既有A的方法和属性
}

2.1、所以只对A类赋值,不对B类进行任何操作

//this 指向当前对象
$A = new A();
$A->setName('I am A;');// 此方法的 $this 指向 A类,所以对 A类属性赋值

$B = new B();

echo $A->getName();
echo '<br/>';
echo $B->getName();

输出结果:

2.2、A、B类同时操作

$A = new A();
$A->setName('I am A;');// 此方法的 $this 指向 A类,所以对 A类属性赋值

$B = new B();
$B->setName('I am B;');//此方法的 $this 指向 B类, 所以对B类属性(继承A)赋值

echo $A->getName();
echo '<br/>';
echo $B->getName();

输出结果:

2.3、结论

A类 的赋值始终没有影响到 B类 的值;所以 $this 的操作只影响了当前类,不会影响了 类的继承;

3、self 关键字

首先:需要明确一点  self是指向类本身,self 跟 任何已经实例化的对象 没有任何关系

测试类如下:

<?php 
declare (strict_types = 1);
class A 
{
    static public $name;
    function setName(string $name) 
    {
        self::$name = $name;
    }
    function getName()
    {
        var_dump(self::$name);
    }
}
class B extends A
{    
    //这里B继承A但是不做任何操作,
    //B也既有A的方法和属性
}

3.1、 A类进行操作

// B类的属性和方法来自 A类, self 此时指向 A类
$A = new A();
$A->setName('I am A;');// 此方法的 self 指向类本身,所以对 A 类的赋值,会影响到 B类

$B = new B();

echo $A->getName();
echo '<br/>';
echo $B->getName();

输出结果:

3.2、A类,B类同时操作

//B类的属性和方法来自 A类, self 此时指向 A类
$A = new A();
$A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,会影响到 B类

$B = new B();
$B->setName('I am B;');// 此方法的 self 指向 A类,所以对 B 类的赋值,会影响到 A类

echo $A->getName();
echo '<br/>';
echo $B->getName();

输出结果:

3.3、 B类重写 A类全部的方法和属性

<?php 
declare (strict_types = 1);
class A 
{
    static public $name;
    function setName(string $name) 
    {
        self::$name = $name;
    }
    function getName()
    {
        var_dump(self::$name);
    }
}

class B extends A
{    
    //现在 B类拥有了自己的方法和属性
    static public $name;
    function setName(string $name) 
    {
        self::$name = $name;
    }
    function getName()
    {
        var_dump(self::$name);
    }
}
//B类重写了A类所有的方法和属性,所以 self(A) 指向 A类, self(B)指向 B类,
$A = new A();
$A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,不会影响到 B类

$B = new B();
$B->setName('I am B;');// 此方法的 self 指向 B类,所以对 B 类的赋值,不会影响到 A类

echo $A->getName();
echo '<br/>';
echo $B->getName();
输出结果:

3.4、B类重新 A类 部分方法和属性

<?php 
declare (strict_types = 1);
class A 
{
    static public $name;
    function setName(string $name) 
    {
        self::$name = $name;
    }
    function getName()
    {
        var_dump(self::$name);
    }
}

class B extends A
{    
    //现在 B类拥有了部分自己的方法和属性
    static public $name;
    function setName(string $name) 
    {
        self::$name = $name;
    }

}
// getName 的方法 继承来自 A类,所以 getName 中的 self指向 A类
$A = new A();
$A->setName('I am A;');// 此方法的 self 指向 A类,所以对 A 类的赋值,不会影响到 B类

$B = new B();
$B->setName('I am B;');// 此方法的 self 指向 B类,所以对 B 类的赋值,不会影响到 A类

echo $A->getName();// 此方法的 self 指向 A类
echo '<br/>';
echo $B->getName();// 此方法的 self 指向 A类

结果输出:

3.5、结论

从上面三组测试,不难看出,前两个例子,$name 属性只有 A类有, B类虽然继承了(还不是自己的),所以 self::$name 无论条件都指向了 A类,导致结果都一样,而第三个例子,当赋予了 B类自己的属性和方法了(重新了A类,self 就跟 A类没有任何关系了,指向了 B类),而第四个例子则看出,B 类的 getName 方法继承了A类,所以self 指向了A类。

结语:self 指向类本身(他跟谁实例化他没关系,值关系到他属于那个类)

4、parent 关键字

首先:需要明确

  1. php 是单继承,父类永远只有一个
  2. parent 只能调用方法,不能调用属性
  3. parent 不会改变this指向

4.1、调用父类带this的方法

<?php 
declare (strict_types = 1);
class A 
{
    public $name;
    function setName(string $name) 
    {
        $this->name = $name;
    }
    function getName()
    {
        var_dump($this->name);
    }
}

class B extends A
{    
    function getName()
    {
        var_dump($this->name);
    }
    function getNameParent() 
    {
        parent::getName();
    }

}

$A = new A();
$A->setName('I am A;');

$B = new B();
echo $A->getName();
echo '<br/>';
echo $B->getName();
echo '<br/>';
echo $B->getNameParent();//调用 A类的方法,当其中的 $this 还是指向 B类(就近(姑且这样理解))

输出结果:

4.2、当 A 类的方法是固定输出时

<?php 
declare (strict_types = 1);
class A 
{
    public $name;
    function setName(string $name) 
    {
        $this->name = $name;
    }
    function getName()
    {
        // var_dump($this->name);
        echo '欢迎使用 A类方法';
    }
}

class B extends A
{    
    function getName()
    {
        echo '欢迎使用 B类方法';
    }
    function getNameParent() 
    {
        parent::getName();
    }

}

$A = new A();
$A->setName('I am A;');

$B = new B();
echo $A->getName();
echo '<br/>';
echo $B->getName();
echo '<br/>';
echo $B->getNameParent();//调用 A类的方法,当其中的 $this 还是指向 B类(就近(姑且这样理解))

输出结果:

4.3、结语

parent 指向 父类,但是不能改变 父类方法中 this 的指向, 而且只能访问 (public 和 protected ),对于private 会报错

5、总结

  • this  是指向当前类(就近原则,离谁近跟谁)
  • self  是指向当前类(一般是静态变量,静态方法用,指本身)
  • parent是指向父类(php是单继承,父类也就只有一个)

基本上我所了解就这么多,肯定有理解错误之处,请高手指出!

posted @ 2017-11-17 22:25  一切随风飘  阅读(824)  评论(0编辑  收藏  举报