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 关键字
首先:需要明确
- 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是单继承,父类也就只有一个)
基本上我所了解就这么多,肯定有理解错误之处,请高手指出!