self,this,parent 这三个关键字在 类的使用中可谓屡见不鲜,那么这三个关键字又有什么区别;
从字面意思理解:
- this 是指向当前类(就近原则,离谁近跟谁)
- self 是指向当前类(一般是静态变量,静态方法用,指本身)
- parent是指向父类(php是单继承,父类也就只有一个)
2、this 关键字
测试类如下:
<?phpdeclare (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 关键字
首先:需要明确
- php 是单继承,父类永远只有一个
- parent 只能调用方法,不能调用属性
- 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是单继承,父类也就只有一个)
基本上我所了解就这么多,肯定有理解错误之处,请高手指出!