Home > Article > Backend Development > this 在继承的类中指向父类?
<?phpclass pa{ private function m(){ echo 'Parent\'s function'; } public function run(){ $this->m(); }}class child extends pa{ public function m(){ echo 'child\'s function'; }}$obj=new child();$obj->run();
没有找到更详细的解释extends作用机理的文章,以下只是我的猜测
我觉得造成这种问题的原因可能在于,虽然表面上是继承了父类,但是父类实际上是存在的,也就是说,如果通过子类的实例化对象来调用父类中的某个方法,那么实际上它进入到了父类的空间里,那么在父类空间里的$this的作用范围就是父类空间本身,而不能跨越到子类的空间中。
之所以会这么猜想,是因为PHP的变量的引用原理,也就是当一个变量的值,是另一个变量的引用时,并不等同于这两个变量变成了同一个变量,其实本身还是两个变量,并且销毁其中一个的时候,另一个仍然存在。
所以基于此我认为,子类的实例化对象不应该使用父类中的$this来代表子类的对象,这样会造成对象的“越级”
还是那句话:私有的是不可侵犯的
楼上回复真心精辟啊!
没有找到更详细的解释extends作用机理的文章,以下只是我的猜测
我觉得造成这种问题的原因可能在于,虽然表面上是继承了父类,但是父类实际上是存在的,也就是说,如果通过子类的实例化对象来调用父类中的某个方法,那么实际上它进入到了父类的空间里,那么在父类空间里的$this的作用范围就是父类空间本身,而不能跨越到子类的空间中。
之所以会这么猜想,是因为PHP的变量的引用原理,也就是当一个变量的值,是另一个变量的引用时,并不等同于这两个变量变成了同一个变量,其实本身还是两个变量,并且销毁其中一个的时候,另一个仍然存在。
所以基于此我认为,子类的实例化对象不应该使用父类中的$this来代表子类的对象,这样会造成对象的“越级”
public 和 private结果是不一样的,当属性变为public,this就代表子类,能解释吗
如果父类是Class A,子类是Class B,个人觉得内存结构应该是这样
A = Class A
B = { (继承自Class A) Class B }
子类对象创建的时候,应该是先创建了父类对象,然后父类的内存块作为子类内存块的一部分(子类=父类内存结构+子类自有)
所以父类中的定义的this调用的方法要么是 父类的方法,要么是 父类中被子类重写的。
你的子类实例中没有定义run方法,访问的就是父类的公共方法run,此时$this应该已经是指向父类了,所以$this->m()调用的就是父类中未被重写的私有m方法
B = { (继承自Class A)
比如下面这里例子
<?phpclass pa{ public function a(){ $this->sd(); // $this指向父类,而父类中未定义sd方法,子类的sd方法又是私有的,所以没有输出,子类的sd改成public即可输出。 }}class child extends pa{ public function m(){ $this->a(); } private function sd(){ echo 'sd'; }}$obj=new child();$obj->m();
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
private 私有的,只能被自己访问。不会被继承和覆盖
public 共有的,可任意访问、继承、覆盖
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
因为对于php来说 public 和 private 是2种不同的修饰
也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
没有找到更详细的解释extends作用机理的文章,以下只是我的猜测
我觉得造成这种问题的原因可能在于,虽然表面上是继承了父类,但是父类实际上是存在的,也就是说,如果通过子类的实例化对象来调用父类中的某个方法,那么实际上它进入到了父类的空间里,那么在父类空间里的$this的作用范围就是父类空间本身,而不能跨越到子类的空间中。
之所以会这么猜想,是因为PHP的变量的引用原理,也就是当一个变量的值,是另一个变量的引用时,并不等同于这两个变量变成了同一个变量,其实本身还是两个变量,并且销毁其中一个的时候,另一个仍然存在。
所以基于此我认为,子类的实例化对象不应该使用父类中的$this来代表子类的对象,这样会造成对象的“越级”
public 和 private结果是不一样的,当属性变为public,this就代表子类,能解释吗
按照上面各位大大的解释,private是不能被覆盖的,而public可以被覆盖,所以你改为public之后,就是父类的方法被子类覆盖了
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
因为对于php来说 public 和 private 是2种不同的修饰
也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
run()方法已经是子类的方法了,那么$child->run()执行的就是子类自己的方法,run()里面的this也是出现在子类中,指代子类对象,那么$this->m()调用的因该是子类的m()而不是父类的m(),我这么理解的。子类和父类的m()没关系,这点我在帖子中已经说了m()没被继承,我的问题是run()方法里面的this指向,为什么在private和public情况下不同,谢谢
private 私有的,只能被自己访问。不会被继承和覆盖
public 共有的,可任意访问、继承、覆盖
答非所问
没有找到更详细的解释extends作用机理的文章,以下只是我的猜测
我觉得造成这种问题的原因可能在于,虽然表面上是继承了父类,但是父类实际上是存在的,也就是说,如果通过子类的实例化对象来调用父类中的某个方法,那么实际上它进入到了父类的空间里,那么在父类空间里的$this的作用范围就是父类空间本身,而不能跨越到子类的空间中。
之所以会这么猜想,是因为PHP的变量的引用原理,也就是当一个变量的值,是另一个变量的引用时,并不等同于这两个变量变成了同一个变量,其实本身还是两个变量,并且销毁其中一个的时候,另一个仍然存在。
所以基于此我认为,子类的实例化对象不应该使用父类中的$this来代表子类的对象,这样会造成对象的“越级”
public 和 private结果是不一样的,当属性变为public,this就代表子类,能解释吗
按照上面各位大大的解释,private是不能被覆盖的,而public可以被覆盖,所以你改为public之后,就是父类的方法被子类覆盖了
那与this的指向有什么关系?
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
因为对于php来说 public 和 private 是2种不同的修饰
也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
run()方法已经是子类的方法了,那么$child->run()执行的就是子类自己的方法,run()里面的this也是出现在子类中,指代子类对象,那么$this->m()调用的因该是子类的m()而不是父类的m(),我这么理解的。子类和父类的m()没关系,这点我在帖子中已经说了m()没被继承,我的问题是run()方法里面的this指向,为什么在private和public情况下不同,谢谢
run()啥时候是子类方法了,你run是定义在父类里的啊。它的public表示它可以被子类访问和重写,不代表它就直接属于子类的方法啊。
$child->run()执行时$child实例里是没有run方法的。所以按照8楼所说,因为child是子类,所以在子类中找不到时到父类空间中找,这时父类中的run方法中的$this就是表示父类本身。
你使用$this->m()时,由于$this目前表示父类,而m()又是private的,所以不存在被覆盖的可能,子类里定义的是属于子类自己的,跟父类无关。调用的就是父类的m,而不是子类。
当你把父类的m()的private改成public,父类的m()就存在被重写的可能,所以程序会去继承他的子类中去寻找(也就是你的$child),如果找到则调用子类的,没找到调用父类自己的m()
第一种请看等价于:
<?phpclass child{ private function m(){ echo 'Parent\'s function'; } public function run(){ $this->m(); } public function m(){ echo 'child\'s function'; }}$obj=new child();$obj->run();
搞错了,请无视。竟然不能编辑。。
$this 是类实例化后的对象
所以 $this 指向的是对象,而不是类
实例化后,无论是基类还是继承类的方法都在对象中
具体执行的是哪个方法由 php 根据规则决定
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa pa::m Parent's function
class pa{ public function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa child::m child's function
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); parent::run(); }}$obj=new child();$obj->run();得到
还是那句话:私有的是不可侵犯的
好精辟啊
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
因为对于php来说 public 和 private 是2种不同的修饰
也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
run()方法已经是子类的方法了,那么$child->run()执行的就是子类自己的方法,run()里面的this也是出现在子类中,指代子类对象,那么$this->m()调用的因该是子类的m()而不是父类的m(),我这么理解的。子类和父类的m()没关系,这点我在帖子中已经说了m()没被继承,我的问题是run()方法里面的this指向,为什么在private和public情况下不同,谢谢
run()啥时候是子类方法了,你run是定义在父类里的啊。它的public表示它可以被子类访问和重写,不代表它就直接属于子类的方法啊。
$child->run()执行时$child实例里是没有run方法的。所以按照8楼所说,因为child是子类,所以在子类中找不到时到父类空间中找,这时父类中的run方法中的$this就是表示父类本身。
你使用$this->m()时,由于$this目前表示父类,而m()又是private的,所以不存在被覆盖的可能,子类里定义的是属于子类自己的,跟父类无关。调用的就是父类的m,而不是子类。
当你把父类的m()的private改成public,父类的m()就存在被重写的可能,所以程序会去继承他的子类中去寻找(也就是你的$child),如果找到则调用子类的,没找到调用父类自己的m()
这时父类中的run方法中的$this就是表示父类本身。按这么说,你的理论就是,实力化子类的时候,父类也实例化了?this只能引用对象不能引用类,你的意思是创建子类的时候,顺便把父类实例化了?否则this这个东西就是个矛盾,都不存在父类对象,哪存在this
$this 是实例化后的对象
就像 $obj=new child(); 后的 $obj 一样
如果你是在对象内部访问对象的方法和属性的话,总不能老是要把 $obj 传进去吧?
所以就有了 $this 这个载体
其实所有面向对象的语言中都有这个 this,也的确迷糊了众多的初学者。其实没有什么好不理解的
this 就是对象自己
$this 是类实例化后的对象
所以 $this 指向的是对象,而不是类
实例化后,无论是基类还是继承类的方法都在对象中
具体执行的是哪个方法由 php 根据规则决定
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa pa::m Parent's function
class pa{ public function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; }}$obj=new child();$obj->run();得到 pa child::m child's function
class pa{ private function m(){ echo __METHOD__ . ' Parent\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); }}class child extends pa{ public function m(){ echo __METHOD__ . ' child\'s function'; } public function run(){ echo __CLASS__ . ' '; $this->m(); parent::run(); }}$obj=new child();$obj->run();得到
$this 是实例化后的对象
就像 $obj=new child(); 后的 $obj 一样
如果你是在对象内部访问对象的方法和属性的话,总不能老是要把 $obj 传进去吧?
所以就有了 $this 这个载体
其实所有面向对象的语言中都有这个 this,也的确迷糊了众多的初学者。其实没有什么好不理解的
this 就是对象自己
你说的这个我明白,我真正不明白的地方是,子类继承父类方法function a()(这个方法a()内用到了this),这个继承过来的this,到底是谁的this?13楼的回答看得出来他明白了我是什么意思,但是解释的有矛盾,而版主还是没理解我的意思,我不是不明白private和this的规则,我市不知道在继承过程中,this传到了子类的过程中,指向发生了改变还是怎么回事,你的前2个代码的运行结果,明显是php运行机制中的矛盾点
没有什么子类对象和分类对象
也不存在“子类实例化前,父类也必须先实例化”
实例化的只是一个类
只不过这个类可能包还有继承过来的方法和属性
再重复一遍:this 就是对象自己
既然这样,那么继承过来的子类应该等同于下面把
class child extends pa{ public function m(){ echo 'child\'s function'; } public function run(){//只继承了run(),m()私有,没继承 $this->m(); }}
还是那句话:私有的是不可侵犯的
没明白,怎么解释public 和 private结果不同
因为对于php来说 public 和 private 是2种不同的修饰
也就是说,当父类是private m时,子类的public m其实只是子类的内部方法,而和父类完全没有关系,当调用run时,首先回去run声明的空间寻找private的方法,如果找到,则直接执行,否则回去当前对象的空间寻找public或者protected的方法,如果还没有找到,并且有extends class 则会去class的空间找,仍然没有的话,则会报错。
run()方法已经是子类的方法了,那么$child->run()执行的就是子类自己的方法,run()里面的this也是出现在子类中,指代子类对象,那么$this->m()调用的因该是子类的m()而不是父类的m(),我这么理解的。子类和父类的m()没关系,这点我在帖子中已经说了m()没被继承,我的问题是run()方法里面的this指向,为什么在private和public情况下不同,谢谢
最后回复一帖,不想在这个问题多做纠结了
首先,看下面这个例子
<?phpclass pa{ private function m(){ echo 'Parent\'s function'; }}class child extends pa{ public function run(){ if(is_callable($this, 'm')) { echo 'private function can callable'; } else { echo 'private function can not callable'; } }}$obj=new child();if(method_exists($obj, 'm')) { echo 'private function can extends';} else { echo 'private function can not extends';}$obj->run();
<?phpfunction print_method($obj) { $refObj = new ReflectionObject($obj); foreach($refObj->getMethods() as $refFun) { echo "Define class name : ", $refFun->getDeclaringClass()->getName(), "\n"; echo "Modifiers for method ", $refFun->name,":\n"; echo $refFun->getModifiers() . "\n"; echo implode(' ', Reflection::getModifierNames($refFun->getModifiers())) . "\n"; }} class pa{ private function m(){ echo 'Parent\'s function'; } public function run(){ print_method($this); // 从上面的输出可以看到,$this = $obj, // 这里隐含一个输出,为什么会隐藏,这就是继承的关系,我们知道public和protected会被子类同名给覆盖 // 但是private又会被保护,不能覆盖,那么其实就是有2份m,一个private m,另外一个就是子类 public m $this->m(); // 而这里的m调用时,会找那个m调用呢? // 很简单,就是优先找当前method所定义class处的private,因为有了private就不用考虑继承覆盖的问题 } protected}class child extends pa{ public function m(){ echo 'child\'s function'; }}$obj=new child();print_method($obj);$obj->run();
貌似要你那么做需要延迟静态绑定
私有的无论是不是父类都不能调用
$this 是实例化后的对象
就像 $obj=new child(); 后的 $obj 一样
如果你是在对象内部访问对象的方法和属性的话,总不能老是要把 $obj 传进去吧?
所以就有了 $this 这个载体
其实所有面向对象的语言中都有这个 this,也的确迷糊了众多的初学者。其实没有什么好不理解的
this 就是对象自己
应该是他本身吧!无论这个他是父类或子类、或者别的类?
?爆了~~~ 留名学习中~